summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-11-23 21:47:25 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2017-11-29 15:56:57 -0300
commit42910df106420eb7c01ef2ad497eab1b61c6c669 (patch)
tree27ff87ff2b6a011a517be3ca9042d1d8edadcc78
parent95ac35c5570645790494e3acc41cc9c0ccb9e83c (diff)
eolian_cxx: Many changes for the C# bindings
- Added helper function to get all methods of a given class (local and inherited methods) - Add filename information to klass - Added new defs: enum, value (currently only integers), struct - Generator refactoring - Eolian C compatibility
-rw-r--r--src/lib/eolian_cxx/grammar/address_of.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/alternative.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_conditional.hpp15
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_reorder.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_replace.hpp9
-rw-r--r--src/lib/eolian_cxx/grammar/base_class_definition.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/c_type.hpp6
-rw-r--r--src/lib/eolian_cxx/grammar/case.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/class_declaration.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/class_definition.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/class_implementation.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/context.hpp20
-rw-r--r--src/lib/eolian_cxx/grammar/converting_argument.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/eps.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/function_declaration.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/function_definition.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/generator.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/header_guards.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/header_include_directive.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/implementation_include_directive.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/indentation.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/integral.hpp88
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp265
-rw-r--r--src/lib/eolian_cxx/grammar/kleene.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/list.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/namespace.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/parameter.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/sequence.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/string.hpp38
-rw-r--r--src/lib/eolian_cxx/grammar/type.hpp4
30 files changed, 448 insertions, 49 deletions
diff --git a/src/lib/eolian_cxx/grammar/address_of.hpp b/src/lib/eolian_cxx/grammar/address_of.hpp
index 3fa48b0d5d..6c6b977ca3 100644
--- a/src/lib/eolian_cxx/grammar/address_of.hpp
+++ b/src/lib/eolian_cxx/grammar/address_of.hpp
@@ -61,6 +61,8 @@ struct address_of_generator
61 61
62template <> 62template <>
63struct is_eager_generator<address_of_generator> : std::true_type {}; 63struct is_eager_generator<address_of_generator> : std::true_type {};
64template <>
65struct is_generator<address_of_generator> : std::true_type {};
64 66
65namespace type_traits { 67namespace type_traits {
66template <> 68template <>
diff --git a/src/lib/eolian_cxx/grammar/alternative.hpp b/src/lib/eolian_cxx/grammar/alternative.hpp
index 3ad3e6af67..844f3d208d 100644
--- a/src/lib/eolian_cxx/grammar/alternative.hpp
+++ b/src/lib/eolian_cxx/grammar/alternative.hpp
@@ -30,6 +30,8 @@ struct alternative_generator
30 30
31template <typename L, typename R> 31template <typename L, typename R>
32struct is_eager_generator<alternative_generator<L, R> > : std::true_type {}; 32struct is_eager_generator<alternative_generator<L, R> > : std::true_type {};
33template <typename L, typename R>
34struct is_generator<alternative_generator<L, R> > : std::true_type {};
33 35
34namespace type_traits { 36namespace type_traits {
35template <typename L, typename R> 37template <typename L, typename R>
diff --git a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
index 2803f9fc48..5934564014 100644
--- a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
+++ b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
@@ -21,9 +21,6 @@ struct functional_attribute_conditional_generator
21 G g; 21 G g;
22}; 22};
23 23
24template <typename F, typename G>
25struct is_eager_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
26
27template <typename F> 24template <typename F>
28struct functional_attribute_conditional_directive 25struct functional_attribute_conditional_directive
29{ 26{
@@ -42,9 +39,6 @@ struct functional_attribute_conditional_directive
42 F f; 39 F f;
43}; 40};
44 41
45template <typename F>
46struct is_eager_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
47
48struct attribute_conditional_terminal 42struct attribute_conditional_terminal
49{ 43{
50 template <typename F> 44 template <typename F>
@@ -54,6 +48,15 @@ struct attribute_conditional_terminal
54 } 48 }
55} const attribute_conditional = {}; 49} const attribute_conditional = {};
56 50
51template <typename F, typename G>
52struct is_eager_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
53template <typename F>
54struct is_eager_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
55template <typename F, typename G>
56struct is_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
57template <typename F>
58struct is_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
59
57namespace type_traits { 60namespace type_traits {
58template <typename F, typename G> 61template <typename F, typename G>
59struct attributes_needed<functional_attribute_conditional_generator<F, G>> 62struct attributes_needed<functional_attribute_conditional_generator<F, G>>
diff --git a/src/lib/eolian_cxx/grammar/attribute_reorder.hpp b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp
index b3f8b3196b..a14e3a9203 100644
--- a/src/lib/eolian_cxx/grammar/attribute_reorder.hpp
+++ b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp
@@ -66,6 +66,8 @@ struct attribute_reorder_generator
66 66
67template <typename G, int...S> 67template <typename G, int...S>
68struct is_eager_generator<attribute_reorder_generator<G, S...>> : std::true_type {}; 68struct is_eager_generator<attribute_reorder_generator<G, S...>> : std::true_type {};
69template <typename G, int...S>
70struct is_generator<attribute_reorder_generator<G, S...>> : std::true_type {};
69 71
70template <int...S, typename G> 72template <int...S, typename G>
71attribute_reorder_generator<G, S...> attribute_reorder(G g) 73attribute_reorder_generator<G, S...> attribute_reorder(G g)
diff --git a/src/lib/eolian_cxx/grammar/attribute_replace.hpp b/src/lib/eolian_cxx/grammar/attribute_replace.hpp
index e45fb9f710..fee7328488 100644
--- a/src/lib/eolian_cxx/grammar/attribute_replace.hpp
+++ b/src/lib/eolian_cxx/grammar/attribute_replace.hpp
@@ -18,9 +18,6 @@ struct functional_attribute_replace_generator
18 G g; 18 G g;
19}; 19};
20 20
21template <typename F, typename G>
22struct is_eager_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
23
24template <typename F> 21template <typename F>
25struct functional_attribute_replace_directive 22struct functional_attribute_replace_directive
26{ 23{
@@ -39,8 +36,14 @@ struct functional_attribute_replace_directive
39 F f; 36 F f;
40}; 37};
41 38
39template <typename F, typename G>
40struct is_eager_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
42template <typename F> 41template <typename F>
43struct is_eager_generator<functional_attribute_replace_directive<F>> : std::true_type {}; 42struct is_eager_generator<functional_attribute_replace_directive<F>> : std::true_type {};
43template <typename F, typename G>
44struct is_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
45template <typename F>
46struct is_generator<functional_attribute_replace_directive<F>> : std::true_type {};
44 47
45struct attribute_replace_terminal 48struct attribute_replace_terminal
46{ 49{
diff --git a/src/lib/eolian_cxx/grammar/base_class_definition.hpp b/src/lib/eolian_cxx/grammar/base_class_definition.hpp
index 5a4a219529..aa61334020 100644
--- a/src/lib/eolian_cxx/grammar/base_class_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/base_class_definition.hpp
@@ -101,6 +101,8 @@ struct base_class_definition_generator
101 101
102template <> 102template <>
103struct is_eager_generator<base_class_definition_generator> : std::true_type {}; 103struct is_eager_generator<base_class_definition_generator> : std::true_type {};
104template <>
105struct is_generator<base_class_definition_generator> : std::true_type {};
104 106
105namespace type_traits { 107namespace type_traits {
106template <> 108template <>
diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp b/src/lib/eolian_cxx/grammar/c_type.hpp
index 6d814f80a4..e680b38835 100644
--- a/src/lib/eolian_cxx/grammar/c_type.hpp
+++ b/src/lib/eolian_cxx/grammar/c_type.hpp
@@ -35,10 +35,10 @@ inline std::string c_type(parameter_def const& param)
35 switch(param.direction) 35 switch(param.direction)
36 { 36 {
37 case parameter_direction::in: 37 case parameter_direction::in:
38 return param.type.original_type.visit(c_type_visitor{&param.c_type}); 38 return param.type.original_type.visit(c_type_visitor{&param.type.c_type});
39 case parameter_direction::out: 39 case parameter_direction::out:
40 case parameter_direction::inout: 40 case parameter_direction::inout:
41 return param.type.original_type.visit(c_type_visitor{&param.c_type}) + "*"; 41 return param.type.original_type.visit(c_type_visitor{&param.type.c_type}) + "*";
42 default: 42 default:
43 throw std::runtime_error("Unknown parameter direction"); 43 throw std::runtime_error("Unknown parameter direction");
44 }; 44 };
@@ -63,6 +63,8 @@ struct c_type_generator
63 63
64template <> 64template <>
65struct is_eager_generator<c_type_generator> : std::true_type {}; 65struct is_eager_generator<c_type_generator> : std::true_type {};
66template <>
67struct is_generator<c_type_generator> : std::true_type {};
66 68
67namespace type_traits { 69namespace type_traits {
68template <> 70template <>
diff --git a/src/lib/eolian_cxx/grammar/case.hpp b/src/lib/eolian_cxx/grammar/case.hpp
index 86421363ac..c18d4ab565 100644
--- a/src/lib/eolian_cxx/grammar/case.hpp
+++ b/src/lib/eolian_cxx/grammar/case.hpp
@@ -55,6 +55,10 @@ template <typename G>
55struct is_eager_generator<lower_case_generator<G>> : std::true_type {}; 55struct is_eager_generator<lower_case_generator<G>> : std::true_type {};
56template <typename G> 56template <typename G>
57struct is_eager_generator<upper_case_generator<G>> : std::true_type {}; 57struct is_eager_generator<upper_case_generator<G>> : std::true_type {};
58template <typename G>
59struct is_generator<lower_case_generator<G>> : std::true_type {};
60template <typename G>
61struct is_generator<upper_case_generator<G>> : std::true_type {};
58 62
59namespace type_traits { 63namespace type_traits {
60template <typename G> 64template <typename G>
diff --git a/src/lib/eolian_cxx/grammar/class_declaration.hpp b/src/lib/eolian_cxx/grammar/class_declaration.hpp
index d448c31074..de9c4a69d6 100644
--- a/src/lib/eolian_cxx/grammar/class_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/class_declaration.hpp
@@ -73,6 +73,8 @@ struct class_declaration_generator
73 73
74template <> 74template <>
75struct is_eager_generator<class_declaration_generator> : std::true_type {}; 75struct is_eager_generator<class_declaration_generator> : std::true_type {};
76template <>
77struct is_generator<class_declaration_generator> : std::true_type {};
76 78
77namespace type_traits { 79namespace type_traits {
78template <> 80template <>
diff --git a/src/lib/eolian_cxx/grammar/class_definition.hpp b/src/lib/eolian_cxx/grammar/class_definition.hpp
index 54df3301a6..13349d4007 100644
--- a/src/lib/eolian_cxx/grammar/class_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/class_definition.hpp
@@ -212,6 +212,8 @@ struct class_definition_generator
212 212
213template <> 213template <>
214struct is_eager_generator<class_definition_generator> : std::true_type {}; 214struct is_eager_generator<class_definition_generator> : std::true_type {};
215template <>
216struct is_generator<class_definition_generator> : std::true_type {};
215 217
216namespace type_traits { 218namespace type_traits {
217template <> 219template <>
diff --git a/src/lib/eolian_cxx/grammar/class_implementation.hpp b/src/lib/eolian_cxx/grammar/class_implementation.hpp
index 3e9174f936..0731e3d591 100644
--- a/src/lib/eolian_cxx/grammar/class_implementation.hpp
+++ b/src/lib/eolian_cxx/grammar/class_implementation.hpp
@@ -53,6 +53,8 @@ struct class_implementation_generator
53 53
54template <> 54template <>
55struct is_eager_generator<class_implementation_generator> : std::true_type {}; 55struct is_eager_generator<class_implementation_generator> : std::true_type {};
56template <>
57struct is_generator<class_implementation_generator> : std::true_type {};
56 58
57namespace type_traits { 59namespace type_traits {
58template <> 60template <>
diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp
index 9b5e164470..79e54178e0 100644
--- a/src/lib/eolian_cxx/grammar/context.hpp
+++ b/src/lib/eolian_cxx/grammar/context.hpp
@@ -40,6 +40,26 @@ template <typename Tag>
40struct tag_check<Tag, context_null> : std::false_type {}; 40struct tag_check<Tag, context_null> : std::false_type {};
41template <typename Tag, typename OtherTag, typename Context> 41template <typename Tag, typename OtherTag, typename Context>
42struct tag_check<Tag, context_cons<OtherTag, Context>> : tag_check<Tag, Context> {}; 42struct tag_check<Tag, context_cons<OtherTag, Context>> : tag_check<Tag, Context> {};
43
44template <typename Tag, typename SameTag, typename Tail>
45Tag const& context_find_tag(context_cons<SameTag, Tail> const& context
46 , typename std::enable_if<std::is_same<Tag, SameTag>::value>::type* = nullptr)
47{
48 return context.tag;
49}
50
51template <typename Tag, typename OtherTag, typename Tail>
52Tag const& context_find_tag(context_cons<OtherTag, Tail> const& context
53 , typename std::enable_if<!std::is_same<Tag, OtherTag>::value>::type* = nullptr)
54{
55 return context_find_tag<Tag>(context.tail);
56}
57
58template <typename Tag, typename OtherTag, typename Tail>
59Tag const& context_find_tag(context_null const& context)
60{
61 throw std::logic_error("Context for generation not available");
62}
43 63
44} } } 64} } }
45 65
diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp
index 07255800ca..230608ffc3 100644
--- a/src/lib/eolian_cxx/grammar/converting_argument.hpp
+++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp
@@ -68,6 +68,8 @@ struct converting_argument_generator
68 68
69template <> 69template <>
70struct is_eager_generator<converting_argument_generator> : std::true_type {}; 70struct is_eager_generator<converting_argument_generator> : std::true_type {};
71template <>
72struct is_generator<converting_argument_generator> : std::true_type {};
71 73
72namespace type_traits { 74namespace type_traits {
73template <> 75template <>
diff --git a/src/lib/eolian_cxx/grammar/eps.hpp b/src/lib/eolian_cxx/grammar/eps.hpp
index 900df90e1a..d396cbf0b3 100644
--- a/src/lib/eolian_cxx/grammar/eps.hpp
+++ b/src/lib/eolian_cxx/grammar/eps.hpp
@@ -16,6 +16,8 @@ struct eps_generator
16 16
17template <> 17template <>
18struct is_eager_generator<eps_generator> : std::true_type {}; 18struct is_eager_generator<eps_generator> : std::true_type {};
19template <>
20struct is_generator<eps_generator> : std::true_type {};
19 21
20eps_generator const eps = {}; 22eps_generator const eps = {};
21 23
diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp
index 431b4a21da..e98fbf0a3a 100644
--- a/src/lib/eolian_cxx/grammar/function_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp
@@ -57,6 +57,8 @@ struct function_declaration_generator
57 57
58template <> 58template <>
59struct is_eager_generator<function_declaration_generator> : std::true_type {}; 59struct is_eager_generator<function_declaration_generator> : std::true_type {};
60template <>
61struct is_generator<function_declaration_generator> : std::true_type {};
60 62
61namespace type_traits { 63namespace type_traits {
62template <> 64template <>
diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp
index 1c7cf25a16..50bd9970c5 100644
--- a/src/lib/eolian_cxx/grammar/function_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/function_definition.hpp
@@ -88,7 +88,7 @@ struct function_definition_generator
88 if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false; 88 if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false;
89 89
90 if(f.return_type != attributes::void_ 90 if(f.return_type != attributes::void_
91 && !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", f.return_type.c_type}) 91 && !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, ""})
92 << " __return_value = " 92 << " __return_value = "
93 ).generate(sink, attributes::unused, ctx)) return false; 93 ).generate(sink, attributes::unused, ctx)) return false;
94 94
@@ -154,6 +154,8 @@ struct function_definition_generator
154 154
155template <> 155template <>
156struct is_eager_generator<function_definition_generator> : std::true_type {}; 156struct is_eager_generator<function_definition_generator> : std::true_type {};
157template <>
158struct is_generator<function_definition_generator> : std::true_type {};
157 159
158namespace type_traits { 160namespace type_traits {
159template <> 161template <>
diff --git a/src/lib/eolian_cxx/grammar/generator.hpp b/src/lib/eolian_cxx/grammar/generator.hpp
index 1100befddf..130ee6859c 100644
--- a/src/lib/eolian_cxx/grammar/generator.hpp
+++ b/src/lib/eolian_cxx/grammar/generator.hpp
@@ -38,8 +38,8 @@ template <typename T>
38struct is_generator<T volatile const&> : is_generator<T> {}; 38struct is_generator<T volatile const&> : is_generator<T> {};
39template <typename T> 39template <typename T>
40struct is_eager_generator<T volatile const&> : is_eager_generator<T> {}; 40struct is_eager_generator<T volatile const&> : is_eager_generator<T> {};
41template <typename T> 41// template <typename T>
42struct is_generator<T> : is_eager_generator<T> {}; 42// struct is_generator<T> : is_eager_generator<T> {};
43 43
44template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type> 44template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type>
45G as_generator(G&& g) { return g; } 45G as_generator(G&& g) { return g; }
diff --git a/src/lib/eolian_cxx/grammar/header_guards.hpp b/src/lib/eolian_cxx/grammar/header_guards.hpp
index eab596d91e..a5a353bb4b 100644
--- a/src/lib/eolian_cxx/grammar/header_guards.hpp
+++ b/src/lib/eolian_cxx/grammar/header_guards.hpp
@@ -56,6 +56,8 @@ struct header_guards_generator
56 56
57template <typename G> 57template <typename G>
58struct is_eager_generator<header_guards_generator<G> > : std::true_type {}; 58struct is_eager_generator<header_guards_generator<G> > : std::true_type {};
59template <typename G>
60struct is_generator<header_guards_generator<G> > : std::true_type {};
59 61
60namespace type_traits { 62namespace type_traits {
61template <typename G> 63template <typename G>
diff --git a/src/lib/eolian_cxx/grammar/header_include_directive.hpp b/src/lib/eolian_cxx/grammar/header_include_directive.hpp
index 8fbc0eb4fa..6b717b685a 100644
--- a/src/lib/eolian_cxx/grammar/header_include_directive.hpp
+++ b/src/lib/eolian_cxx/grammar/header_include_directive.hpp
@@ -21,6 +21,8 @@ struct header_include_directive_generator
21 21
22template <> 22template <>
23struct is_eager_generator<header_include_directive_generator> : std::true_type {}; 23struct is_eager_generator<header_include_directive_generator> : std::true_type {};
24template <>
25struct is_generator<header_include_directive_generator> : std::true_type {};
24 26
25namespace type_traits { 27namespace type_traits {
26template <> 28template <>
diff --git a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp
index f82d84b9ea..1fe50df6f7 100644
--- a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp
+++ b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp
@@ -32,6 +32,8 @@ struct implementation_include_directive_generator
32 32
33template <> 33template <>
34struct is_eager_generator<implementation_include_directive_generator> : std::true_type {}; 34struct is_eager_generator<implementation_include_directive_generator> : std::true_type {};
35template <>
36struct is_generator<implementation_include_directive_generator> : std::true_type {};
35 37
36namespace type_traits { 38namespace type_traits {
37template <> 39template <>
diff --git a/src/lib/eolian_cxx/grammar/indentation.hpp b/src/lib/eolian_cxx/grammar/indentation.hpp
index 615842e87b..897be03c3b 100644
--- a/src/lib/eolian_cxx/grammar/indentation.hpp
+++ b/src/lib/eolian_cxx/grammar/indentation.hpp
@@ -28,6 +28,8 @@ struct scope_tab_generator
28 28
29template <> 29template <>
30struct is_eager_generator<scope_tab_generator> : std::true_type {}; 30struct is_eager_generator<scope_tab_generator> : std::true_type {};
31template <>
32struct is_generator<scope_tab_generator> : std::true_type {};
31 33
32struct scope_tab_terminal 34struct scope_tab_terminal
33{ 35{
diff --git a/src/lib/eolian_cxx/grammar/integral.hpp b/src/lib/eolian_cxx/grammar/integral.hpp
new file mode 100644
index 0000000000..95cb2f0740
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/integral.hpp
@@ -0,0 +1,88 @@
1#ifndef EOLIAN_CXX_INTEGRAL_HH
2#define EOLIAN_CXX_INTEGRAL_HH
3
4#include <cstdlib>
5#include <cstring>
6
7#include "grammar/generator.hpp"
8#include "grammar/attributes.hpp"
9#include "grammar/case.hpp"
10
11namespace efl { namespace eolian { namespace grammar {
12
13namespace detail {
14
15template <typename OutputIterator, typename T>
16void generate_integral(OutputIterator sink, T integer)
17{
18 std::stringstream stm;
19 stm << integer;
20 std::string string = stm.str();
21 std::copy(string.begin(), string.end(), sink);
22}
23
24}
25
26// literal
27template <typename T>
28struct literal_integral_generator
29{
30 T integral;
31
32 template <typename OutputIterator, typename Attribute, typename Context>
33 bool generate(OutputIterator sink, Attribute const&, Context const&) const
34 {
35 detail::generate_integral(sink, integral);
36 return true;
37 }
38};
39
40template <typename T, typename Enable = typename std::enable_if<std::is_integral<T>::value>::type>
41literal_integral_generator<T> as_generator(T&& literal) { return {std::forward<T>(literal)}; }
42literal_integral_generator<std::size_t> as_generator(std::size_t literal) { return {literal}; }
43
44struct integral_terminal {
45 template <typename T>
46 literal_integral_generator<T> operator()(T literal) const
47 {
48 return {literal};
49 }
50} const int_ = {};
51
52struct integral_generator
53{
54 template <typename OutputIterator, typename Attribute, typename Context>
55 bool generate(OutputIterator sink, Attribute const& attribute, Context const&) const
56 {
57 detail::generate_integral(sink, attribute);
58 return true;
59 }
60};
61
62integral_generator as_generator(integral_terminal) { return {}; }
63
64template <typename T>
65struct is_eager_generator<literal_integral_generator<T>> : std::true_type {};
66template <>
67struct is_eager_generator<integral_generator> : std::true_type {};
68template <typename T>
69struct is_generator<literal_integral_generator<T>> : std::true_type {};
70template <>
71struct is_generator<integral_generator> : std::true_type {};
72template <typename T>
73struct is_generator<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::true_type {};
74template <>
75struct is_generator<integral_terminal> : std::true_type {};
76
77namespace type_traits {
78template <typename T>
79struct attributes_needed<literal_integral_generator<T>> : std::integral_constant<int, 0> {};
80template <>
81struct attributes_needed<integral_generator> : std::integral_constant<int, 1> {};
82template <>
83struct attributes_needed<integral_terminal> : std::integral_constant<int, 1> {};
84}
85
86} } }
87
88#endif
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index 146bfbe861..edfadc05bb 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -212,16 +212,19 @@ struct type_def
212 typedef eina::variant<klass_name, regular_type_def, complex_type_def> variant_type; 212 typedef eina::variant<klass_name, regular_type_def, complex_type_def> variant_type;
213 variant_type original_type; 213 variant_type original_type;
214 std::string c_type; 214 std::string c_type;
215 bool has_own;
216 bool is_ptr;
215 217
216 type_def() {} 218 type_def() {}
217 type_def(variant_type original_type, std::string c_type) 219 type_def(variant_type original_type, std::string c_type, bool has_own)
218 : original_type(original_type), c_type(c_type) {} 220 : original_type(original_type), c_type(c_type), has_own(has_own) {}
219 221
220 type_def(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype) 222 type_def(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
221 { 223 {
222 set(eolian_type, unit, ctype); 224 set(eolian_type, unit, ctype);
223 } 225 }
224 void set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype); 226 void set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype);
227 void set(Eolian_Expression_Type eolian_exp_type);
225}; 228};
226 229
227struct get_qualifier_visitor 230struct get_qualifier_visitor
@@ -247,17 +250,19 @@ inline bool operator!=(type_def const& lhs, type_def const& rhs)
247 return !(lhs == rhs); 250 return !(lhs == rhs);
248} 251}
249 252
250type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void"}; 253type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}, false}, "void", false};
251 254
252inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype) 255inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
253{ 256{
254 c_type = ::eolian_type_c_type_get(eolian_type, ctype); 257 c_type = ::eolian_type_c_type_get(eolian_type, ctype);
255 // ::eina_stringshare_del(stringshare); // this crashes 258 // ::eina_stringshare_del(stringshare); // this crashes
256 Eolian_Type const* stp = eolian_type_base_type_get(eolian_type); 259 Eolian_Type const* stp = eolian_type_base_type_get(eolian_type);
260 has_own = !!::eolian_type_is_owned(eolian_type);
261 is_ptr = !!::eolian_type_is_ptr(eolian_type);
257 switch( ::eolian_type_type_get(eolian_type)) 262 switch( ::eolian_type_type_get(eolian_type))
258 { 263 {
259 case EOLIAN_TYPE_VOID: 264 case EOLIAN_TYPE_VOID:
260 original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}}; 265 original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}, false};
261 break; 266 break;
262 case EOLIAN_TYPE_REGULAR: 267 case EOLIAN_TYPE_REGULAR:
263 if (!stp) 268 if (!stp)
@@ -305,6 +310,22 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
305 } 310 }
306} 311}
307 312
313inline void type_def::set(Eolian_Expression_Type eolian_exp_type)
314{
315 switch(eolian_exp_type)
316 {
317 case EOLIAN_EXPR_INT:
318 original_type = attributes::regular_type_def{"int", {{}, {}}, {}, false};
319 c_type = "int";
320 break;
321 default:
322 // FIXME implement the remaining types
323 EINA_LOG_ERR("Unsupported expression type");
324 std::abort();
325 break;
326 }
327}
328
308enum class parameter_direction 329enum class parameter_direction
309{ 330{
310 in, inout, out 331 in, inout, out
@@ -331,26 +352,23 @@ struct parameter_def
331 parameter_direction direction; 352 parameter_direction direction;
332 type_def type; 353 type_def type;
333 std::string param_name; 354 std::string param_name;
334 std::string c_type;
335 355
336 friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs) 356 friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs)
337 { 357 {
338 return lhs.direction == rhs.direction 358 return lhs.direction == rhs.direction
339 && lhs.type == rhs.type 359 && lhs.type == rhs.type
340 && lhs.param_name == rhs.param_name 360 && lhs.param_name == rhs.param_name;
341 && lhs.c_type == rhs.c_type;
342 } 361 }
343 friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs) 362 friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs)
344 { 363 {
345 return !(lhs == rhs); 364 return !(lhs == rhs);
346 } 365 }
347 366
348 parameter_def(parameter_direction direction, type_def type, std::string param_name, std::string c_type) 367 parameter_def(parameter_direction direction, type_def type, std::string param_name)
349 : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), c_type(std::move(c_type)) {} 368 : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)) {}
350 parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit) 369 parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit)
351 : type( ::eolian_parameter_type_get(param), unit, EOLIAN_C_TYPE_PARAM) 370 : type( ::eolian_parameter_type_get(param), unit, EOLIAN_C_TYPE_PARAM)
352 , param_name( ::eolian_parameter_name_get(param)) 371 , param_name( ::eolian_parameter_name_get(param))
353 , c_type( ::eolian_type_c_type_get(::eolian_parameter_type_get(param), EOLIAN_C_TYPE_PARAM))
354 { 372 {
355 Eolian_Parameter_Dir direction = ::eolian_parameter_direction_get(param); 373 Eolian_Parameter_Dir direction = ::eolian_parameter_direction_get(param);
356 switch(direction) 374 switch(direction)
@@ -396,8 +414,8 @@ template <>
396struct tuple_element<3ul, parameter_def> 414struct tuple_element<3ul, parameter_def>
397{ 415{
398 typedef std::string type; 416 typedef std::string type;
399 static type const& get(parameter_def const& p) { return p.c_type; } 417 static type const& get(parameter_def const& p) { return p.type.c_type; }
400 static type& get(parameter_def& p) { return p.c_type; } 418 static type& get(parameter_def& p) { return p.type.c_type; }
401}; 419};
402template <int I> 420template <int I>
403typename tuple_element<I, parameter_def>::type const& get(parameter_def const& p) 421typename tuple_element<I, parameter_def>::type const& get(parameter_def const& p)
@@ -412,6 +430,7 @@ struct function_def
412 std::string name; 430 std::string name;
413 std::vector<parameter_def> parameters; 431 std::vector<parameter_def> parameters;
414 std::string c_name; 432 std::string c_name;
433 std::string filename;
415 bool is_beta; 434 bool is_beta;
416 bool is_protected; 435 bool is_protected;
417 436
@@ -421,6 +440,7 @@ struct function_def
421 && lhs.name == rhs.name 440 && lhs.name == rhs.name
422 && lhs.parameters == rhs.parameters 441 && lhs.parameters == rhs.parameters
423 && lhs.c_name == rhs.c_name 442 && lhs.c_name == rhs.c_name
443 && lhs.filename == rhs.filename
424 && lhs.is_beta == rhs.is_beta 444 && lhs.is_beta == rhs.is_beta
425 && lhs.is_protected == rhs.is_protected; 445 && lhs.is_protected == rhs.is_protected;
426 } 446 }
@@ -430,8 +450,8 @@ struct function_def
430 } 450 }
431 451
432 function_def(type_def return_type, std::string name, std::vector<parameter_def> parameters 452 function_def(type_def return_type, std::string name, std::vector<parameter_def> parameters
433 , std::string c_name, bool is_beta) 453 , std::string c_name, std::string filename, bool is_beta)
434 : return_type(return_type), name(name), parameters(parameters), c_name(c_name), is_beta(is_beta) {} 454 : return_type(return_type), name(name), parameters(parameters), c_name(c_name), filename(filename), is_beta(is_beta) {}
435 function_def() = default; 455 function_def() = default;
436 function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit) 456 function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit)
437 : return_type(void_) 457 : return_type(void_)
@@ -440,7 +460,7 @@ struct function_def
440 name = ::eolian_function_name_get(function); 460 name = ::eolian_function_name_get(function);
441 if(r_type) 461 if(r_type)
442 return_type.set(r_type, unit, EOLIAN_C_TYPE_RETURN); 462 return_type.set(r_type, unit, EOLIAN_C_TYPE_RETURN);
443 if(type == EOLIAN_METHOD) 463 if(type == EOLIAN_METHOD || type == EOLIAN_FUNCTION_POINTER)
444 { 464 {
445 for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( ::eolian_function_parameters_get(function)) 465 for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( ::eolian_function_parameters_get(function))
446 , param_last; param_iterator != param_last; ++param_iterator) 466 , param_last; param_iterator != param_last; ++param_iterator)
@@ -484,8 +504,18 @@ struct function_def
484 parameters.insert(parameters.end(), values.begin(), values.end()); 504 parameters.insert(parameters.end(), values.begin(), values.end());
485 } 505 }
486 c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE); 506 c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE);
507 if (type != EOLIAN_FUNCTION_POINTER)
508 {
509 const Eolian_Class *klass = eolian_function_class_get(function);
510 filename = eolian_class_file_get(klass);
511 }
512 else
513 {
514 filename = "";
515 }
487 is_beta = eolian_function_is_beta(function); 516 is_beta = eolian_function_is_beta(function);
488 is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED; 517 is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
518 is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
489 } 519 }
490}; 520};
491 521
@@ -606,20 +636,25 @@ auto get(event_def& def) -> decltype(tuple_element<N, event_def>::get(def))
606 return tuple_element<N, event_def>::get(def); 636 return tuple_element<N, event_def>::get(def);
607} 637}
608 638
639inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit);
640
609struct klass_def 641struct klass_def
610{ 642{
611 std::string eolian_name; 643 std::string eolian_name;
612 std::string cxx_name; 644 std::string cxx_name;
645 std::string filename;
613 std::vector<std::string> namespaces; 646 std::vector<std::string> namespaces;
614 std::vector<function_def> functions; 647 std::vector<function_def> functions;
615 std::set<klass_name, compare_klass_name_by_name> inherits; 648 std::set<klass_name, compare_klass_name_by_name> inherits;
616 class_type type; 649 class_type type;
617 std::vector<event_def> events; 650 std::vector<event_def> events;
651 std::set<klass_name, compare_klass_name_by_name> immediate_inherits;
618 652
619 friend inline bool operator==(klass_def const& lhs, klass_def const& rhs) 653 friend inline bool operator==(klass_def const& lhs, klass_def const& rhs)
620 { 654 {
621 return lhs.eolian_name == rhs.eolian_name 655 return lhs.eolian_name == rhs.eolian_name
622 && lhs.cxx_name == rhs.cxx_name 656 && lhs.cxx_name == rhs.cxx_name
657 && lhs.filename == lhs.filename
623 && lhs.namespaces == rhs.namespaces 658 && lhs.namespaces == rhs.namespaces
624 && lhs.functions == rhs.functions 659 && lhs.functions == rhs.functions
625 && lhs.inherits == rhs.inherits 660 && lhs.inherits == rhs.inherits
@@ -631,14 +666,16 @@ struct klass_def
631 return !(lhs == rhs); 666 return !(lhs == rhs);
632 } 667 }
633 668
634 klass_def(std::string eolian_name, std::string cxx_name 669 klass_def(std::string eolian_name, std::string cxx_name, std::string filename
635 , std::vector<std::string> namespaces 670 , std::vector<std::string> namespaces
636 , std::vector<function_def> functions 671 , std::vector<function_def> functions
637 , std::set<klass_name, compare_klass_name_by_name> inherits 672 , std::set<klass_name, compare_klass_name_by_name> inherits
638 , class_type type) 673 , class_type type
639 : eolian_name(eolian_name), cxx_name(cxx_name) 674 , std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
675 : eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
640 , namespaces(namespaces) 676 , namespaces(namespaces)
641 , functions(functions), inherits(inherits), type(type) 677 , functions(functions), inherits(inherits), type(type)
678 , immediate_inherits(immediate_inherits)
642 {} 679 {}
643 klass_def(Eolian_Class const* klass, Eolian_Unit const* unit) 680 klass_def(Eolian_Class const* klass, Eolian_Unit const* unit)
644 { 681 {
@@ -648,6 +685,7 @@ struct klass_def
648 this->namespaces.push_back(&*namespace_iterator); 685 this->namespaces.push_back(&*namespace_iterator);
649 } 686 }
650 cxx_name = eolian_name = eolian_class_name_get(klass); 687 cxx_name = eolian_name = eolian_class_name_get(klass);
688 filename = eolian_class_file_get(klass);
651 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY)) 689 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY))
652 , functions_last; eolian_functions != functions_last; ++eolian_functions) 690 , functions_last; eolian_functions != functions_last; ++eolian_functions)
653 { 691 {
@@ -684,6 +722,12 @@ struct klass_def
684 functions.push_back({function, EOLIAN_METHOD, unit}); 722 functions.push_back({function, EOLIAN_METHOD, unit});
685 } catch(std::exception const&) {} 723 } catch(std::exception const&) {}
686 } 724 }
725 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(klass))
726 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
727 {
728 Eolian_Class const* inherit = &*inherit_iterator;
729 immediate_inherits.insert({inherit, {}});
730 }
687 std::function<void(Eolian_Class const*)> inherit_algo = 731 std::function<void(Eolian_Class const*)> inherit_algo =
688 [&] (Eolian_Class const* klass) 732 [&] (Eolian_Class const* klass)
689 { 733 {
@@ -722,6 +766,117 @@ struct klass_def
722 } 766 }
723 } 767 }
724 768
769 // TODO memoize the return?
770 std::vector<function_def> get_all_methods() const
771 {
772 std::vector<function_def> ret;
773
774 std::copy(functions.cbegin(), functions.cend(), std::back_inserter(ret));
775
776 for (auto inherit : inherits)
777 {
778 klass_def klass(get_klass(inherit, NULL), NULL);
779 std::copy(klass.functions.cbegin(), klass.functions.cend(),
780 std::back_inserter(ret));
781 }
782
783 return ret;
784 }
785};
786
787struct value_def
788{
789 typedef eina::variant<int> variant_type; // FIXME support other types
790 variant_type value;
791 std::string literal;
792 type_def type;
793
794 value_def() {}
795 value_def(Eolian_Value value_obj)
796 {
797 type.set(value_obj.type);
798 value = value_obj.value.i;
799 literal = eolian_expression_value_to_literal(&value_obj);
800 }
801};
802
803struct enum_value_def
804{
805 value_def value;
806 std::string name;
807 std::string c_name;
808
809 enum_value_def(Eolian_Enum_Type_Field const* enum_field)
810 {
811 name = eolian_typedecl_enum_field_name_get(enum_field);
812 c_name = eolian_typedecl_enum_field_c_name_get(enum_field);
813 auto exp = eolian_typedecl_enum_field_value_get(enum_field, EINA_TRUE);
814 value = eolian_expression_eval(NULL, exp, EOLIAN_MASK_INT); // FIXME hardcoded int
815 }
816};
817
818struct enum_def
819{
820 std::string eolian_name;
821 std::string cxx_name;
822 std::vector<std::string> namespaces;
823 std::vector<enum_value_def> fields;
824
825 enum_def(Eolian_Typedecl const* enum_obj)
826 {
827 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(enum_obj))
828 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
829 {
830 this->namespaces.push_back((&*namespace_iterator));
831 }
832 cxx_name = eolian_name = eolian_typedecl_name_get(enum_obj);
833
834 for (efl::eina::iterator<const Eolian_Enum_Type_Field> field_iterator(::eolian_typedecl_enum_fields_get(enum_obj))
835 , field_last; field_iterator != field_last; ++field_iterator)
836 {
837 // Fill the types
838 this->fields.push_back(&*field_iterator);
839 }
840 }
841};
842
843struct struct_field_def
844{
845 type_def type;
846 std::string name;
847
848 struct_field_def(Eolian_Struct_Type_Field const* struct_field)
849 {
850 name = eolian_typedecl_struct_field_name_get(struct_field);
851 try {
852 type.set(eolian_typedecl_struct_field_type_get(struct_field), NULL, EOLIAN_C_TYPE_DEFAULT);
853 } catch(std::runtime_error const&) { /* Silently skip pointer fields*/ }
854 }
855
856};
857
858struct struct_def
859{
860 std::string eolian_name;
861 std::string cxx_name;
862 std::vector<std::string> namespaces;
863 std::vector<struct_field_def> fields;
864
865 struct_def(Eolian_Typedecl const* struct_obj)
866 {
867 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(struct_obj))
868 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
869 {
870 this->namespaces.push_back((&*namespace_iterator));
871 }
872 cxx_name = eolian_name = eolian_typedecl_name_get(struct_obj);
873
874 for(efl::eina::iterator<const Eolian_Struct_Type_Field> field_iterator(::eolian_typedecl_struct_fields_get(struct_obj))
875 , field_last; field_iterator != field_last; ++field_iterator)
876 {
877 this->fields.push_back(&*field_iterator);
878 }
879 }
725}; 880};
726 881
727inline klass_name get_klass_name(klass_def const& klass) 882inline klass_name get_klass_name(klass_def const& klass)
@@ -748,6 +903,80 @@ inline std::vector<std::string> cpp_namespaces(std::vector<std::string> namespac
748 return namespaces; 903 return namespaces;
749} 904}
750 905
906inline bool has_events(klass_def const &klass)
907{
908 for (auto&& e : klass.events)
909 {
910 (void)e;
911 return true;
912 }
913
914 for (auto&& c : klass.inherits)
915 {
916 attributes::klass_def parent(get_klass(c, NULL), NULL);
917 for (auto&& e : parent.events)
918 {
919 (void)e;
920 return true;
921 }
922 }
923
924 return false;
925}
926
927template<typename T>
928inline bool has_type_return(klass_def const &klass, T visitor)
929{
930 for (auto&& f : klass.functions)
931 {
932 if (f.return_type.original_type.visit(visitor))
933 return true;
934 }
935
936 for (auto&& c : klass.inherits)
937 {
938 attributes::klass_def parent(get_klass(c, NULL), NULL);
939 if (has_type_return(parent, visitor))
940 return true;
941 }
942
943 return false;
944}
945
946struct string_return_visitor
947{
948 typedef string_return_visitor visitor_type;
949 typedef bool result_type;
950 template <typename T>
951 bool operator()(T const&) const { return false; }
952 bool operator()(regular_type_def const& regular) const
953 {
954 return regular.base_type == "string";
955 }
956};
957
958struct stringshare_return_visitor
959{
960 typedef stringshare_return_visitor visitor_type;
961 typedef bool result_type;
962 template <typename T>
963 bool operator()(T const&) const { return false; }
964 bool operator()(regular_type_def const& regular) const
965 {
966 return regular.base_type == "stringshare";
967 }
968};
969
970inline bool has_string_return(klass_def const &klass)
971{
972 return has_type_return(klass, string_return_visitor{});
973}
974
975inline bool has_stringshare_return(klass_def const &klass)
976{
977 return has_type_return(klass, stringshare_return_visitor{});
978}
979
751} 980}
752namespace type_traits { 981namespace type_traits {
753 982
diff --git a/src/lib/eolian_cxx/grammar/kleene.hpp b/src/lib/eolian_cxx/grammar/kleene.hpp
index 8c3088fb03..0aff2bae20 100644
--- a/src/lib/eolian_cxx/grammar/kleene.hpp
+++ b/src/lib/eolian_cxx/grammar/kleene.hpp
@@ -29,6 +29,8 @@ struct kleene_generator
29 29
30template <typename Generator> 30template <typename Generator>
31struct is_eager_generator<kleene_generator<Generator> > : std::true_type {}; 31struct is_eager_generator<kleene_generator<Generator> > : std::true_type {};
32template <typename Generator>
33struct is_generator<kleene_generator<Generator> > : std::true_type {};
32 34
33namespace type_traits { 35namespace type_traits {
34template <typename G> 36template <typename G>
diff --git a/src/lib/eolian_cxx/grammar/list.hpp b/src/lib/eolian_cxx/grammar/list.hpp
index c8d96240d8..f87a771b66 100644
--- a/src/lib/eolian_cxx/grammar/list.hpp
+++ b/src/lib/eolian_cxx/grammar/list.hpp
@@ -34,6 +34,8 @@ struct list_generator
34 34
35template <typename G, typename S> 35template <typename G, typename S>
36struct is_eager_generator<list_generator<G, S> > : std::true_type {}; 36struct is_eager_generator<list_generator<G, S> > : std::true_type {};
37template <typename G, typename S>
38struct is_generator<list_generator<G, S> > : std::true_type {};
37 39
38namespace type_traits { 40namespace type_traits {
39template <typename G, typename S> 41template <typename G, typename S>
diff --git a/src/lib/eolian_cxx/grammar/namespace.hpp b/src/lib/eolian_cxx/grammar/namespace.hpp
index 5cef9ecfe8..e16edca8f1 100644
--- a/src/lib/eolian_cxx/grammar/namespace.hpp
+++ b/src/lib/eolian_cxx/grammar/namespace.hpp
@@ -54,6 +54,8 @@ struct namespaces_directive
54 54
55template <typename G> 55template <typename G>
56struct is_eager_generator<namespaces_generator<G>> : std::true_type {}; 56struct is_eager_generator<namespaces_generator<G>> : std::true_type {};
57template <typename G>
58struct is_generator<namespaces_generator<G>> : std::true_type {};
57 59
58namespace type_traits { 60namespace type_traits {
59template <typename G> 61template <typename G>
diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp
index b29805e24a..f9e625a514 100644
--- a/src/lib/eolian_cxx/grammar/parameter.hpp
+++ b/src/lib/eolian_cxx/grammar/parameter.hpp
@@ -35,6 +35,8 @@ struct parameter_type_generator
35 35
36template <> 36template <>
37struct is_eager_generator<parameter_type_generator> : std::true_type {}; 37struct is_eager_generator<parameter_type_generator> : std::true_type {};
38template <>
39struct is_generator<parameter_type_generator> : std::true_type {};
38namespace type_traits { 40namespace type_traits {
39template <> 41template <>
40struct attributes_needed<parameter_type_generator> : std::integral_constant<int, 1> {}; 42struct attributes_needed<parameter_type_generator> : std::integral_constant<int, 1> {};
@@ -53,6 +55,8 @@ struct parameter_generator
53 55
54template <> 56template <>
55struct is_eager_generator<parameter_generator> : std::true_type {}; 57struct is_eager_generator<parameter_generator> : std::true_type {};
58template <>
59struct is_generator<parameter_generator> : std::true_type {};
56namespace type_traits { 60namespace type_traits {
57template <> 61template <>
58struct attributes_needed<parameter_generator> : std::integral_constant<int, 1> {}; 62struct attributes_needed<parameter_generator> : std::integral_constant<int, 1> {};
diff --git a/src/lib/eolian_cxx/grammar/sequence.hpp b/src/lib/eolian_cxx/grammar/sequence.hpp
index 96fb467af2..dfffbf3394 100644
--- a/src/lib/eolian_cxx/grammar/sequence.hpp
+++ b/src/lib/eolian_cxx/grammar/sequence.hpp
@@ -115,6 +115,8 @@ struct sequence_generator
115 115
116template <typename L, typename R> 116template <typename L, typename R>
117struct is_eager_generator<sequence_generator<L, R> > : std::true_type {}; 117struct is_eager_generator<sequence_generator<L, R> > : std::true_type {};
118template <typename L, typename R>
119struct is_generator<sequence_generator<L, R> > : std::true_type {};
118 120
119namespace type_traits { 121namespace type_traits {
120template <typename L, typename R> 122template <typename L, typename R>
diff --git a/src/lib/eolian_cxx/grammar/string.hpp b/src/lib/eolian_cxx/grammar/string.hpp
index 77507ce2a0..df4ae8f2cb 100644
--- a/src/lib/eolian_cxx/grammar/string.hpp
+++ b/src/lib/eolian_cxx/grammar/string.hpp
@@ -26,15 +26,6 @@ struct literal_generator
26 const char* string; 26 const char* string;
27}; 27};
28 28
29template <>
30struct is_eager_generator<literal_generator> : std::true_type {};
31
32template <>
33struct is_generator<const char*> : std::true_type {};
34
35template <int N>
36struct is_generator<const char[N]> : std::true_type {};
37
38literal_generator as_generator(char const* literal) { return literal; } 29literal_generator as_generator(char const* literal) { return literal; }
39 30
40struct { 31struct {
@@ -130,13 +121,6 @@ struct string_replace_generator
130 char from, to; 121 char from, to;
131}; 122};
132 123
133template <>
134struct is_eager_generator<string_generator> : std::true_type {};
135template <>
136struct is_eager_generator<specific_string_generator> : std::true_type {};
137template <>
138struct is_eager_generator<string_replace_generator> : std::true_type {};
139
140struct string_generator_terminal 124struct string_generator_terminal
141{ 125{
142 specific_string_generator operator[](std::string string) const 126 specific_string_generator operator[](std::string string) const
@@ -154,6 +138,28 @@ struct string_replace_terminal
154} const string_replace = {}; 138} const string_replace = {};
155 139
156template <> 140template <>
141struct is_eager_generator<literal_generator> : std::true_type {};
142template <>
143struct is_generator<literal_generator> : std::true_type {};
144template <>
145struct is_generator<const char*> : std::true_type {};
146
147template <int N>
148struct is_generator<const char[N]> : std::true_type {};
149template <>
150struct is_eager_generator<string_generator> : std::true_type {};
151template <>
152struct is_eager_generator<specific_string_generator> : std::true_type {};
153template <>
154struct is_eager_generator<string_replace_generator> : std::true_type {};
155template <>
156struct is_generator<string_generator> : std::true_type {};
157template <>
158struct is_generator<specific_string_generator> : std::true_type {};
159template <>
160struct is_generator<string_replace_generator> : std::true_type {};
161
162template <>
157struct is_generator<string_generator_terminal> : std::true_type {}; 163struct is_generator<string_generator_terminal> : std::true_type {};
158template <> 164template <>
159struct is_generator<std::string> : std::true_type {}; 165struct is_generator<std::string> : std::true_type {};
diff --git a/src/lib/eolian_cxx/grammar/type.hpp b/src/lib/eolian_cxx/grammar/type.hpp
index 8a09b6e199..61e0e55fba 100644
--- a/src/lib/eolian_cxx/grammar/type.hpp
+++ b/src/lib/eolian_cxx/grammar/type.hpp
@@ -23,7 +23,7 @@ struct type_generator
23 template <typename OutputIterator, typename Context> 23 template <typename OutputIterator, typename Context>
24 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 24 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
25 { 25 {
26 return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type 26 return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
27 , param.direction != attributes::parameter_direction::in, false}); 27 , param.direction != attributes::parameter_direction::in, false});
28 } 28 }
29 29
@@ -46,6 +46,8 @@ type_generator const as_generator(type_terminal)
46template <> 46template <>
47struct is_eager_generator<type_generator> : std::true_type {}; 47struct is_eager_generator<type_generator> : std::true_type {};
48template <> 48template <>
49struct is_generator<type_generator> : std::true_type {};
50template <>
49struct is_generator<type_terminal> : std::true_type {}; 51struct is_generator<type_terminal> : std::true_type {};
50 52
51namespace type_traits { 53namespace type_traits {