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
This commit is contained in:
Lauro Moura 2017-11-23 21:47:25 -03:00
parent 0931696a4f
commit e6dd831f7e
30 changed files with 448 additions and 49 deletions

View File

@ -61,6 +61,8 @@ struct address_of_generator
template <>
struct is_eager_generator<address_of_generator> : std::true_type {};
template <>
struct is_generator<address_of_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -30,6 +30,8 @@ struct alternative_generator
template <typename L, typename R>
struct is_eager_generator<alternative_generator<L, R> > : std::true_type {};
template <typename L, typename R>
struct is_generator<alternative_generator<L, R> > : std::true_type {};
namespace type_traits {
template <typename L, typename R>

View File

@ -21,9 +21,6 @@ struct functional_attribute_conditional_generator
G g;
};
template <typename F, typename G>
struct is_eager_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
template <typename F>
struct functional_attribute_conditional_directive
{
@ -42,9 +39,6 @@ struct functional_attribute_conditional_directive
F f;
};
template <typename F>
struct is_eager_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
struct attribute_conditional_terminal
{
template <typename F>
@ -54,6 +48,15 @@ struct attribute_conditional_terminal
}
} const attribute_conditional = {};
template <typename F, typename G>
struct is_eager_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
template <typename F>
struct is_eager_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
template <typename F, typename G>
struct is_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
template <typename F>
struct is_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
namespace type_traits {
template <typename F, typename G>
struct attributes_needed<functional_attribute_conditional_generator<F, G>>

View File

@ -66,6 +66,8 @@ struct attribute_reorder_generator
template <typename G, int...S>
struct is_eager_generator<attribute_reorder_generator<G, S...>> : std::true_type {};
template <typename G, int...S>
struct is_generator<attribute_reorder_generator<G, S...>> : std::true_type {};
template <int...S, typename G>
attribute_reorder_generator<G, S...> attribute_reorder(G g)

View File

@ -18,9 +18,6 @@ struct functional_attribute_replace_generator
G g;
};
template <typename F, typename G>
struct is_eager_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
template <typename F>
struct functional_attribute_replace_directive
{
@ -39,8 +36,14 @@ struct functional_attribute_replace_directive
F f;
};
template <typename F, typename G>
struct is_eager_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
template <typename F>
struct is_eager_generator<functional_attribute_replace_directive<F>> : std::true_type {};
template <typename F, typename G>
struct is_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
template <typename F>
struct is_generator<functional_attribute_replace_directive<F>> : std::true_type {};
struct attribute_replace_terminal
{

View File

@ -101,6 +101,8 @@ struct base_class_definition_generator
template <>
struct is_eager_generator<base_class_definition_generator> : std::true_type {};
template <>
struct is_generator<base_class_definition_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -35,10 +35,10 @@ inline std::string c_type(parameter_def const& param)
switch(param.direction)
{
case parameter_direction::in:
return param.type.original_type.visit(c_type_visitor{&param.c_type});
return param.type.original_type.visit(c_type_visitor{&param.type.c_type});
case parameter_direction::out:
case parameter_direction::inout:
return param.type.original_type.visit(c_type_visitor{&param.c_type}) + "*";
return param.type.original_type.visit(c_type_visitor{&param.type.c_type}) + "*";
default:
throw std::runtime_error("Unknown parameter direction");
};
@ -63,6 +63,8 @@ struct c_type_generator
template <>
struct is_eager_generator<c_type_generator> : std::true_type {};
template <>
struct is_generator<c_type_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -55,6 +55,10 @@ template <typename G>
struct is_eager_generator<lower_case_generator<G>> : std::true_type {};
template <typename G>
struct is_eager_generator<upper_case_generator<G>> : std::true_type {};
template <typename G>
struct is_generator<lower_case_generator<G>> : std::true_type {};
template <typename G>
struct is_generator<upper_case_generator<G>> : std::true_type {};
namespace type_traits {
template <typename G>

View File

@ -73,6 +73,8 @@ struct class_declaration_generator
template <>
struct is_eager_generator<class_declaration_generator> : std::true_type {};
template <>
struct is_generator<class_declaration_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -212,6 +212,8 @@ struct class_definition_generator
template <>
struct is_eager_generator<class_definition_generator> : std::true_type {};
template <>
struct is_generator<class_definition_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -53,6 +53,8 @@ struct class_implementation_generator
template <>
struct is_eager_generator<class_implementation_generator> : std::true_type {};
template <>
struct is_generator<class_implementation_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -40,6 +40,26 @@ template <typename Tag>
struct tag_check<Tag, context_null> : std::false_type {};
template <typename Tag, typename OtherTag, typename Context>
struct tag_check<Tag, context_cons<OtherTag, Context>> : tag_check<Tag, Context> {};
template <typename Tag, typename SameTag, typename Tail>
Tag const& context_find_tag(context_cons<SameTag, Tail> const& context
, typename std::enable_if<std::is_same<Tag, SameTag>::value>::type* = nullptr)
{
return context.tag;
}
template <typename Tag, typename OtherTag, typename Tail>
Tag const& context_find_tag(context_cons<OtherTag, Tail> const& context
, typename std::enable_if<!std::is_same<Tag, OtherTag>::value>::type* = nullptr)
{
return context_find_tag<Tag>(context.tail);
}
template <typename Tag, typename OtherTag, typename Tail>
Tag const& context_find_tag(context_null const& context)
{
throw std::logic_error("Context for generation not available");
}
} } }

View File

@ -68,6 +68,8 @@ struct converting_argument_generator
template <>
struct is_eager_generator<converting_argument_generator> : std::true_type {};
template <>
struct is_generator<converting_argument_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -16,6 +16,8 @@ struct eps_generator
template <>
struct is_eager_generator<eps_generator> : std::true_type {};
template <>
struct is_generator<eps_generator> : std::true_type {};
eps_generator const eps = {};

View File

@ -57,6 +57,8 @@ struct function_declaration_generator
template <>
struct is_eager_generator<function_declaration_generator> : std::true_type {};
template <>
struct is_generator<function_declaration_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -88,7 +88,7 @@ struct function_definition_generator
if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false;
if(f.return_type != attributes::void_
&& !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", f.return_type.c_type})
&& !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, ""})
<< " __return_value = "
).generate(sink, attributes::unused, ctx)) return false;
@ -154,6 +154,8 @@ struct function_definition_generator
template <>
struct is_eager_generator<function_definition_generator> : std::true_type {};
template <>
struct is_generator<function_definition_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -38,8 +38,8 @@ template <typename T>
struct is_generator<T volatile const&> : is_generator<T> {};
template <typename T>
struct is_eager_generator<T volatile const&> : is_eager_generator<T> {};
template <typename T>
struct is_generator<T> : is_eager_generator<T> {};
// template <typename T>
// struct is_generator<T> : is_eager_generator<T> {};
template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type>
G as_generator(G&& g) { return g; }

View File

@ -56,6 +56,8 @@ struct header_guards_generator
template <typename G>
struct is_eager_generator<header_guards_generator<G> > : std::true_type {};
template <typename G>
struct is_generator<header_guards_generator<G> > : std::true_type {};
namespace type_traits {
template <typename G>

View File

@ -21,6 +21,8 @@ struct header_include_directive_generator
template <>
struct is_eager_generator<header_include_directive_generator> : std::true_type {};
template <>
struct is_generator<header_include_directive_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -32,6 +32,8 @@ struct implementation_include_directive_generator
template <>
struct is_eager_generator<implementation_include_directive_generator> : std::true_type {};
template <>
struct is_generator<implementation_include_directive_generator> : std::true_type {};
namespace type_traits {
template <>

View File

@ -28,6 +28,8 @@ struct scope_tab_generator
template <>
struct is_eager_generator<scope_tab_generator> : std::true_type {};
template <>
struct is_generator<scope_tab_generator> : std::true_type {};
struct scope_tab_terminal
{

View File

@ -0,0 +1,88 @@
#ifndef EOLIAN_CXX_INTEGRAL_HH
#define EOLIAN_CXX_INTEGRAL_HH
#include <cstdlib>
#include <cstring>
#include "grammar/generator.hpp"
#include "grammar/attributes.hpp"
#include "grammar/case.hpp"
namespace efl { namespace eolian { namespace grammar {
namespace detail {
template <typename OutputIterator, typename T>
void generate_integral(OutputIterator sink, T integer)
{
std::stringstream stm;
stm << integer;
std::string string = stm.str();
std::copy(string.begin(), string.end(), sink);
}
}
// literal
template <typename T>
struct literal_integral_generator
{
T integral;
template <typename OutputIterator, typename Attribute, typename Context>
bool generate(OutputIterator sink, Attribute const&, Context const&) const
{
detail::generate_integral(sink, integral);
return true;
}
};
template <typename T, typename Enable = typename std::enable_if<std::is_integral<T>::value>::type>
literal_integral_generator<T> as_generator(T&& literal) { return {std::forward<T>(literal)}; }
literal_integral_generator<std::size_t> as_generator(std::size_t literal) { return {literal}; }
struct integral_terminal {
template <typename T>
literal_integral_generator<T> operator()(T literal) const
{
return {literal};
}
} const int_ = {};
struct integral_generator
{
template <typename OutputIterator, typename Attribute, typename Context>
bool generate(OutputIterator sink, Attribute const& attribute, Context const&) const
{
detail::generate_integral(sink, attribute);
return true;
}
};
integral_generator as_generator(integral_terminal) { return {}; }
template <typename T>
struct is_eager_generator<literal_integral_generator<T>> : std::true_type {};
template <>
struct is_eager_generator<integral_generator> : std::true_type {};
template <typename T>
struct is_generator<literal_integral_generator<T>> : std::true_type {};
template <>
struct is_generator<integral_generator> : std::true_type {};
template <typename T>
struct is_generator<T, typename std::enable_if<std::is_integral<T>::value>::type> : std::true_type {};
template <>
struct is_generator<integral_terminal> : std::true_type {};
namespace type_traits {
template <typename T>
struct attributes_needed<literal_integral_generator<T>> : std::integral_constant<int, 0> {};
template <>
struct attributes_needed<integral_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed<integral_terminal> : std::integral_constant<int, 1> {};
}
} } }
#endif

View File

@ -212,16 +212,19 @@ struct type_def
typedef eina::variant<klass_name, regular_type_def, complex_type_def> variant_type;
variant_type original_type;
std::string c_type;
bool has_own;
bool is_ptr;
type_def() {}
type_def(variant_type original_type, std::string c_type)
: original_type(original_type), c_type(c_type) {}
type_def(variant_type original_type, std::string c_type, bool has_own)
: original_type(original_type), c_type(c_type), has_own(has_own) {}
type_def(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
{
set(eolian_type, unit, ctype);
}
void set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype);
void set(Eolian_Expression_Type eolian_exp_type);
};
struct get_qualifier_visitor
@ -247,17 +250,19 @@ inline bool operator!=(type_def const& lhs, type_def const& rhs)
return !(lhs == rhs);
}
type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void"};
type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}, false}, "void", false};
inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
{
c_type = ::eolian_type_c_type_get(eolian_type, ctype);
// ::eina_stringshare_del(stringshare); // this crashes
Eolian_Type const* stp = eolian_type_base_type_get(eolian_type);
has_own = !!::eolian_type_is_owned(eolian_type);
is_ptr = !!::eolian_type_is_ptr(eolian_type);
switch( ::eolian_type_type_get(eolian_type))
{
case EOLIAN_TYPE_VOID:
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}};
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}, false};
break;
case EOLIAN_TYPE_REGULAR:
if (!stp)
@ -305,6 +310,22 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
}
}
inline void type_def::set(Eolian_Expression_Type eolian_exp_type)
{
switch(eolian_exp_type)
{
case EOLIAN_EXPR_INT:
original_type = attributes::regular_type_def{"int", {{}, {}}, {}, false};
c_type = "int";
break;
default:
// FIXME implement the remaining types
EINA_LOG_ERR("Unsupported expression type");
std::abort();
break;
}
}
enum class parameter_direction
{
in, inout, out
@ -331,26 +352,23 @@ struct parameter_def
parameter_direction direction;
type_def type;
std::string param_name;
std::string c_type;
friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs)
{
return lhs.direction == rhs.direction
&& lhs.type == rhs.type
&& lhs.param_name == rhs.param_name
&& lhs.c_type == rhs.c_type;
&& lhs.param_name == rhs.param_name;
}
friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs)
{
return !(lhs == rhs);
}
parameter_def(parameter_direction direction, type_def type, std::string param_name, std::string c_type)
: direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), c_type(std::move(c_type)) {}
parameter_def(parameter_direction direction, type_def type, std::string param_name)
: direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)) {}
parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit)
: type( ::eolian_parameter_type_get(param), unit, EOLIAN_C_TYPE_PARAM)
, param_name( ::eolian_parameter_name_get(param))
, c_type( ::eolian_type_c_type_get(::eolian_parameter_type_get(param), EOLIAN_C_TYPE_PARAM))
{
Eolian_Parameter_Dir direction = ::eolian_parameter_direction_get(param);
switch(direction)
@ -396,8 +414,8 @@ template <>
struct tuple_element<3ul, parameter_def>
{
typedef std::string type;
static type const& get(parameter_def const& p) { return p.c_type; }
static type& get(parameter_def& p) { return p.c_type; }
static type const& get(parameter_def const& p) { return p.type.c_type; }
static type& get(parameter_def& p) { return p.type.c_type; }
};
template <int I>
typename tuple_element<I, parameter_def>::type const& get(parameter_def const& p)
@ -412,6 +430,7 @@ struct function_def
std::string name;
std::vector<parameter_def> parameters;
std::string c_name;
std::string filename;
bool is_beta;
bool is_protected;
@ -421,6 +440,7 @@ struct function_def
&& lhs.name == rhs.name
&& lhs.parameters == rhs.parameters
&& lhs.c_name == rhs.c_name
&& lhs.filename == rhs.filename
&& lhs.is_beta == rhs.is_beta
&& lhs.is_protected == rhs.is_protected;
}
@ -430,8 +450,8 @@ struct function_def
}
function_def(type_def return_type, std::string name, std::vector<parameter_def> parameters
, std::string c_name, bool is_beta)
: return_type(return_type), name(name), parameters(parameters), c_name(c_name), is_beta(is_beta) {}
, std::string c_name, std::string filename, bool is_beta)
: return_type(return_type), name(name), parameters(parameters), c_name(c_name), filename(filename), is_beta(is_beta) {}
function_def() = default;
function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit)
: return_type(void_)
@ -440,7 +460,7 @@ struct function_def
name = ::eolian_function_name_get(function);
if(r_type)
return_type.set(r_type, unit, EOLIAN_C_TYPE_RETURN);
if(type == EOLIAN_METHOD)
if(type == EOLIAN_METHOD || type == EOLIAN_FUNCTION_POINTER)
{
for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( ::eolian_function_parameters_get(function))
, param_last; param_iterator != param_last; ++param_iterator)
@ -484,8 +504,18 @@ struct function_def
parameters.insert(parameters.end(), values.begin(), values.end());
}
c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE);
if (type != EOLIAN_FUNCTION_POINTER)
{
const Eolian_Class *klass = eolian_function_class_get(function);
filename = eolian_class_file_get(klass);
}
else
{
filename = "";
}
is_beta = eolian_function_is_beta(function);
is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
}
};
@ -606,20 +636,25 @@ auto get(event_def& def) -> decltype(tuple_element<N, event_def>::get(def))
return tuple_element<N, event_def>::get(def);
}
inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit);
struct klass_def
{
std::string eolian_name;
std::string cxx_name;
std::string filename;
std::vector<std::string> namespaces;
std::vector<function_def> functions;
std::set<klass_name, compare_klass_name_by_name> inherits;
class_type type;
std::vector<event_def> events;
std::set<klass_name, compare_klass_name_by_name> immediate_inherits;
friend inline bool operator==(klass_def const& lhs, klass_def const& rhs)
{
return lhs.eolian_name == rhs.eolian_name
&& lhs.cxx_name == rhs.cxx_name
&& lhs.filename == lhs.filename
&& lhs.namespaces == rhs.namespaces
&& lhs.functions == rhs.functions
&& lhs.inherits == rhs.inherits
@ -631,14 +666,16 @@ struct klass_def
return !(lhs == rhs);
}
klass_def(std::string eolian_name, std::string cxx_name
klass_def(std::string eolian_name, std::string cxx_name, std::string filename
, std::vector<std::string> namespaces
, std::vector<function_def> functions
, std::set<klass_name, compare_klass_name_by_name> inherits
, class_type type)
: eolian_name(eolian_name), cxx_name(cxx_name)
, class_type type
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
, namespaces(namespaces)
, functions(functions), inherits(inherits), type(type)
, immediate_inherits(immediate_inherits)
{}
klass_def(Eolian_Class const* klass, Eolian_Unit const* unit)
{
@ -648,6 +685,7 @@ struct klass_def
this->namespaces.push_back(&*namespace_iterator);
}
cxx_name = eolian_name = eolian_class_name_get(klass);
filename = eolian_class_file_get(klass);
for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY))
, functions_last; eolian_functions != functions_last; ++eolian_functions)
{
@ -684,6 +722,12 @@ struct klass_def
functions.push_back({function, EOLIAN_METHOD, unit});
} catch(std::exception const&) {}
}
for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(klass))
, inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
{
Eolian_Class const* inherit = &*inherit_iterator;
immediate_inherits.insert({inherit, {}});
}
std::function<void(Eolian_Class const*)> inherit_algo =
[&] (Eolian_Class const* klass)
{
@ -722,6 +766,117 @@ struct klass_def
}
}
// TODO memoize the return?
std::vector<function_def> get_all_methods() const
{
std::vector<function_def> ret;
std::copy(functions.cbegin(), functions.cend(), std::back_inserter(ret));
for (auto inherit : inherits)
{
klass_def klass(get_klass(inherit, NULL), NULL);
std::copy(klass.functions.cbegin(), klass.functions.cend(),
std::back_inserter(ret));
}
return ret;
}
};
struct value_def
{
typedef eina::variant<int> variant_type; // FIXME support other types
variant_type value;
std::string literal;
type_def type;
value_def() {}
value_def(Eolian_Value value_obj)
{
type.set(value_obj.type);
value = value_obj.value.i;
literal = eolian_expression_value_to_literal(&value_obj);
}
};
struct enum_value_def
{
value_def value;
std::string name;
std::string c_name;
enum_value_def(Eolian_Enum_Type_Field const* enum_field)
{
name = eolian_typedecl_enum_field_name_get(enum_field);
c_name = eolian_typedecl_enum_field_c_name_get(enum_field);
auto exp = eolian_typedecl_enum_field_value_get(enum_field, EINA_TRUE);
value = eolian_expression_eval(NULL, exp, EOLIAN_MASK_INT); // FIXME hardcoded int
}
};
struct enum_def
{
std::string eolian_name;
std::string cxx_name;
std::vector<std::string> namespaces;
std::vector<enum_value_def> fields;
enum_def(Eolian_Typedecl const* enum_obj)
{
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(enum_obj))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
{
this->namespaces.push_back((&*namespace_iterator));
}
cxx_name = eolian_name = eolian_typedecl_name_get(enum_obj);
for (efl::eina::iterator<const Eolian_Enum_Type_Field> field_iterator(::eolian_typedecl_enum_fields_get(enum_obj))
, field_last; field_iterator != field_last; ++field_iterator)
{
// Fill the types
this->fields.push_back(&*field_iterator);
}
}
};
struct struct_field_def
{
type_def type;
std::string name;
struct_field_def(Eolian_Struct_Type_Field const* struct_field)
{
name = eolian_typedecl_struct_field_name_get(struct_field);
try {
type.set(eolian_typedecl_struct_field_type_get(struct_field), NULL, EOLIAN_C_TYPE_DEFAULT);
} catch(std::runtime_error const&) { /* Silently skip pointer fields*/ }
}
};
struct struct_def
{
std::string eolian_name;
std::string cxx_name;
std::vector<std::string> namespaces;
std::vector<struct_field_def> fields;
struct_def(Eolian_Typedecl const* struct_obj)
{
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(struct_obj))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
{
this->namespaces.push_back((&*namespace_iterator));
}
cxx_name = eolian_name = eolian_typedecl_name_get(struct_obj);
for(efl::eina::iterator<const Eolian_Struct_Type_Field> field_iterator(::eolian_typedecl_struct_fields_get(struct_obj))
, field_last; field_iterator != field_last; ++field_iterator)
{
this->fields.push_back(&*field_iterator);
}
}
};
inline 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
return namespaces;
}
inline bool has_events(klass_def const &klass)
{
for (auto&& e : klass.events)
{
(void)e;
return true;
}
for (auto&& c : klass.inherits)
{
attributes::klass_def parent(get_klass(c, NULL), NULL);
for (auto&& e : parent.events)
{
(void)e;
return true;
}
}
return false;
}
template<typename T>
inline bool has_type_return(klass_def const &klass, T visitor)
{
for (auto&& f : klass.functions)
{
if (f.return_type.original_type.visit(visitor))
return true;
}
for (auto&& c : klass.inherits)
{
attributes::klass_def parent(get_klass(c, NULL), NULL);
if (has_type_return(parent, visitor))
return true;
}
return false;
}
struct string_return_visitor
{
typedef string_return_visitor visitor_type;
typedef bool result_type;
template <typename T>
bool operator()(T const&) const { return false; }
bool operator()(regular_type_def const& regular) const
{
return regular.base_type == "string";
}
};
struct stringshare_return_visitor
{
typedef stringshare_return_visitor visitor_type;
typedef bool result_type;
template <typename T>
bool operator()(T const&) const { return false; }
bool operator()(regular_type_def const& regular) const
{
return regular.base_type == "stringshare";
}
};
inline bool has_string_return(klass_def const &klass)
{
return has_type_return(klass, string_return_visitor{});
}
inline bool has_stringshare_return(klass_def const &klass)
{
return has_type_return(klass, stringshare_return_visitor{});
}
}
namespace type_traits {

View File

@ -29,6 +29,8 @@ struct kleene_generator
template <typename Generator>
struct is_eager_generator<kleene_generator<Generator> > : std::true_type {};
template <typename Generator>
struct is_generator<kleene_generator<Generator> > : std::true_type {};
namespace type_traits {
template <typename G>

View File

@ -34,6 +34,8 @@ struct list_generator
template <typename G, typename S>
struct is_eager_generator<list_generator<G, S> > : std::true_type {};
template <typename G, typename S>
struct is_generator<list_generator<G, S> > : std::true_type {};
namespace type_traits {
template <typename G, typename S>

View File

@ -54,6 +54,8 @@ struct namespaces_directive
template <typename G>
struct is_eager_generator<namespaces_generator<G>> : std::true_type {};
template <typename G>
struct is_generator<namespaces_generator<G>> : std::true_type {};
namespace type_traits {
template <typename G>

View File

@ -35,6 +35,8 @@ struct parameter_type_generator
template <>
struct is_eager_generator<parameter_type_generator> : std::true_type {};
template <>
struct is_generator<parameter_type_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed<parameter_type_generator> : std::integral_constant<int, 1> {};
@ -53,6 +55,8 @@ struct parameter_generator
template <>
struct is_eager_generator<parameter_generator> : std::true_type {};
template <>
struct is_generator<parameter_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed<parameter_generator> : std::integral_constant<int, 1> {};

View File

@ -115,6 +115,8 @@ struct sequence_generator
template <typename L, typename R>
struct is_eager_generator<sequence_generator<L, R> > : std::true_type {};
template <typename L, typename R>
struct is_generator<sequence_generator<L, R> > : std::true_type {};
namespace type_traits {
template <typename L, typename R>

View File

@ -26,15 +26,6 @@ struct literal_generator
const char* string;
};
template <>
struct is_eager_generator<literal_generator> : std::true_type {};
template <>
struct is_generator<const char*> : std::true_type {};
template <int N>
struct is_generator<const char[N]> : std::true_type {};
literal_generator as_generator(char const* literal) { return literal; }
struct {
@ -130,13 +121,6 @@ struct string_replace_generator
char from, to;
};
template <>
struct is_eager_generator<string_generator> : std::true_type {};
template <>
struct is_eager_generator<specific_string_generator> : std::true_type {};
template <>
struct is_eager_generator<string_replace_generator> : std::true_type {};
struct string_generator_terminal
{
specific_string_generator operator[](std::string string) const
@ -153,6 +137,28 @@ struct string_replace_terminal
}
} const string_replace = {};
template <>
struct is_eager_generator<literal_generator> : std::true_type {};
template <>
struct is_generator<literal_generator> : std::true_type {};
template <>
struct is_generator<const char*> : std::true_type {};
template <int N>
struct is_generator<const char[N]> : std::true_type {};
template <>
struct is_eager_generator<string_generator> : std::true_type {};
template <>
struct is_eager_generator<specific_string_generator> : std::true_type {};
template <>
struct is_eager_generator<string_replace_generator> : std::true_type {};
template <>
struct is_generator<string_generator> : std::true_type {};
template <>
struct is_generator<specific_string_generator> : std::true_type {};
template <>
struct is_generator<string_replace_generator> : std::true_type {};
template <>
struct is_generator<string_generator_terminal> : std::true_type {};
template <>

View File

@ -23,7 +23,7 @@ struct type_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
, param.direction != attributes::parameter_direction::in, false});
}
@ -46,6 +46,8 @@ type_generator const as_generator(type_terminal)
template <>
struct is_eager_generator<type_generator> : std::true_type {};
template <>
struct is_generator<type_generator> : std::true_type {};
template <>
struct is_generator<type_terminal> : std::true_type {};
namespace type_traits {