#ifndef EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH #define EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH #include #include #include "eo_types.hh" #include "namespace_generator.hh" namespace efl { namespace eolian { namespace grammar { using std::endl; struct full_name { eo_class const& _cls; bool _from_global; full_name(eo_class const& cls, bool from_global = true) : _cls(cls), _from_global(from_global) {} }; inline std::ostream& operator<<(std::ostream& out, full_name const& x) { if (x._from_global) out << "::"; if(!x._cls.name_space.empty()) out << x._cls.name_space << "::"; return out << x._cls.name; } struct abstract_full_name { eo_class const& _cls; bool _from_golbal; abstract_full_name(eo_class const& cls, bool from_golbal = true) : _cls(cls), _from_golbal(from_golbal) {} }; inline std::ostream& operator<<(std::ostream& out, abstract_full_name const& x) { if (x._from_golbal) out << "::"; return out << abstract_namespace << full_name(x._cls); } struct name_upper { eo_class const& _cls; name_upper(eo_class const& cls) : _cls(cls) {} }; inline std::ostream& operator<<(std::ostream& out, name_upper const& x) { std::string key = x._cls.name; std::transform(key.begin(), key.end(), key.begin(), ::toupper); return out << key; } struct c_type { eolian_type_instance const& _list; c_type(eolian_type_instance const& list) : _list(list) {} }; inline std::ostream& operator<<(std::ostream& out, efl::eolian::grammar::c_type const& x) { assert(x._list.size() > 0); std::string res; for (auto rit = x._list.parts.rbegin(), last = x._list.parts.rend(); rit != last; ++rit) { res = /*type_is_binding(*rit) ? (*rit).binding :*/ (*rit).native; } assert(!res.empty()); return out << res; } struct reinterpret_type { eolian_type_instance const& _type; reinterpret_type(eolian_type_instance const& type) : _type(type) {} }; inline std::ostream& operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x) { assert(x._type.size() > 0); std::string res; for (auto rit = x._type.parts.rbegin(), last = x._type.parts.rend(); rit != last; ++rit) { eolian_type const& t = *rit; if (type_is_complex(t)) res = t.binding + "< " + res + " >"; else res = type_is_binding(t) ? t.binding : t.native; } assert(!res.empty()); if (type_is_binding(x._type.front())) { if (x._type.is_out) res += "*"; else if (x._type.is_optional && x._type.front().binding_requires_optional) res = "::efl::eina::optional< " + res + " >"; } return out << res; } struct type_ownership { eolian_type_instance const& _type; type_ownership(eolian_type_instance const& type) : _type(type) {} }; inline std::ostream& operator<<(std::ostream& out, type_ownership const& x) { out << "std::tuple<"; for (auto it=x._type.parts.begin(), last=x._type.parts.end(); it != last; ++it) { if (it != x._type.parts.begin()) out << ", "; out << ((*it).is_own ? "std::true_type" : "std::false_type"); } return out << ">()"; } struct template_parameter_type { eolian_type_instance const& _type; std::string const& _name; template_parameter_type(eolian_type_instance const& type, std::string const& name) : _type(type) , _name(name) {} }; inline std::ostream& operator<<(std::ostream& out, template_parameter_type const& x) { return out << "F_" << x._name; } struct parameter_type { eolian_type_instance const& _type; std::string const& _name; parameter_type(eolian_type_instance const& t, std::string const& name) : _type(t) , _name(name) {} }; inline std::ostream& operator<<(std::ostream& out, parameter_type const& x) { if(type_is_callback(x._type)) out << template_parameter_type(x._type, x._name); else out << reinterpret_type(x._type); return out; } struct parameter_no_ref_type { eolian_type_instance const& _type; std::string const& _name; parameter_no_ref_type(eolian_type_instance const& type, std::string const& name) : _type(type) , _name(name) {} }; inline std::ostream& operator<<(std::ostream& out, parameter_no_ref_type const& x) { return out << "_no_ref_" << parameter_type(x._type, x._name); } struct parameter_remove_reference_typedef { eolian_type_instance const& _type; std::string const& _name; parameter_remove_reference_typedef(eolian_type_instance const& type, std::string const& name) : _type(type) , _name(name) {} }; inline std::ostream& operator<<(std::ostream& out, parameter_remove_reference_typedef const& x) { out << "typedef typename std::remove_reference<" << parameter_type(x._type, x._name) << ">::type " << parameter_no_ref_type(x._type, x._name) << ";"; return out; } struct to_cxx { eolian_type_instance const& _type; std::string const& _varname; to_cxx(eolian_type_instance const& type, std::string const& varname) : _type(type), _varname(varname) {} }; inline std::ostream& operator<<(std::ostream& out, to_cxx const& x) { if (type_is_binding(x._type)) { out << "::efl::eolian::to_cxx<" << reinterpret_type(x._type) << ">(" << x._varname << ", " << type_ownership(x._type) << ")"; } else out << x._varname; return out; } struct to_c { eolian_type_instance const& _type; std::string const& _varname; to_c(eolian_type_instance const& type, std::string const& varname) : _type(type), _varname(varname) {} }; inline std::ostream& operator<<(std::ostream& out, to_c const& x) { if (type_is_callback(x._type)) out << "::efl::eolian::get_callback<" << type_to_native_str(x._type) << ", " << parameter_no_ref_type(x._type, x._varname) << " >()"; else if (type_is_complex(x._type) && type_is_binding(x._type)) out << "::efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")"; else if (type_is_binding(x._type)) out << "::efl::eolian::to_c(" << x._varname << ")"; else out << x._varname; return out; } } } } #endif // EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH