forked from enlightenment/efl
266 lines
8.3 KiB
C++
266 lines
8.3 KiB
C++
|
|
#ifndef EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|
|
#define EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|
|
|
|
#include <iosfwd>
|
|
#include <string>
|
|
|
|
#include "eo_types.hh"
|
|
#include "tab.hh"
|
|
#include "comment.hh"
|
|
#include "namespace_generator.hh"
|
|
#include "eo_class_constructors_generator.hh"
|
|
#include "eo_class_functions_generator.hh"
|
|
#include "eo_class_events_generator.hh"
|
|
|
|
namespace efl { namespace eolian { namespace grammar {
|
|
|
|
struct eo_class_getter
|
|
{
|
|
eo_class const& _cls;
|
|
eo_class_getter(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, eo_class_getter const& x)
|
|
{
|
|
out << tab(1) << "static Eo_Class const* _eo_class()" << endl
|
|
<< tab(1) << "{" << endl
|
|
<< tab(2) << "return("<< x._cls.eo_name << ");" << endl
|
|
<< tab(1) << "}" << endl << endl;
|
|
return out;
|
|
}
|
|
|
|
struct concrete_eo_ptr_getter
|
|
{
|
|
eo_class const& _cls;
|
|
concrete_eo_ptr_getter(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, concrete_eo_ptr_getter const&)
|
|
{
|
|
out << comment("@internal", 1)
|
|
<< tab(1) << "Eo* _concrete_eo_ptr() const" << endl
|
|
<< tab(1) << "{" << endl
|
|
<< tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl
|
|
<< tab(1) << "}" << endl << endl;
|
|
return out;
|
|
}
|
|
|
|
struct class_implicit_conversion_declaration
|
|
{
|
|
eo_class const& _cls;
|
|
class_implicit_conversion_declaration(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, class_implicit_conversion_declaration const& x)
|
|
{
|
|
out << tab(1) << "operator " << full_name(x._cls) << "() const;" << endl;
|
|
out << tab(1) << "operator " << full_name(x._cls) << "&();" << endl;
|
|
out << tab(1) << "operator " << full_name(x._cls) << " const&() const;" << endl;
|
|
return out << endl;
|
|
}
|
|
|
|
struct class_implicit_conversion_definition
|
|
{
|
|
eo_class const& _cls;
|
|
class_implicit_conversion_definition(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, class_implicit_conversion_definition const& x)
|
|
{
|
|
out << "inline " << abstract_full_name(x._cls) << "::operator "
|
|
<< full_name(x._cls) << "() const" << endl
|
|
<< "{" << endl
|
|
<< tab(1) << "return *static_cast<" << full_name(x._cls)
|
|
<< " const*>(static_cast<void const*>(this));" << endl
|
|
<< "}" << endl << endl;
|
|
|
|
out << "inline " << abstract_full_name(x._cls) << "::operator "
|
|
<< full_name(x._cls) << "&()" << endl
|
|
<< "{" << endl
|
|
<< tab(1) << "return *static_cast<" << full_name(x._cls)
|
|
<< "*>(static_cast<void*>(this));" << endl
|
|
<< "}" << endl << endl;
|
|
|
|
out << "inline " << abstract_full_name(x._cls) << "::operator "
|
|
<< full_name(x._cls) << " const&() const" << endl
|
|
<< "{" << endl
|
|
<< tab(1) << "return *static_cast<" << full_name(x._cls)
|
|
<< " const*>(static_cast<void const*>(this));" << endl
|
|
<< "}" << endl << endl;
|
|
|
|
return out;
|
|
}
|
|
|
|
struct address_of_to_pointer
|
|
{
|
|
eo_class const& _cls;
|
|
bool _is_const;
|
|
address_of_to_pointer(eo_class const& cls, bool is_const)
|
|
: _cls(cls), _is_const(is_const)
|
|
{}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, address_of_to_pointer const& x)
|
|
{
|
|
out << "operator " << full_name(x._cls) << (x._is_const ? " const" : "")
|
|
<< "*() const { return static_cast<" << full_name(x._cls)
|
|
<< (x._is_const ? " const" : "")
|
|
<< "*>(static_cast<D const*>(this)->p); }";
|
|
return out;
|
|
}
|
|
|
|
struct abstract_address_of
|
|
{
|
|
eo_class const& _cls;
|
|
abstract_address_of(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, abstract_address_of const& x)
|
|
{
|
|
out << comment("@cond LOCAL", 1);
|
|
|
|
out << tab(1) << "template <typename D>" << endl
|
|
<< tab(1) << "struct address_of" << endl
|
|
<< tab(1) << "{" << endl
|
|
<< tab(2) << address_of_to_pointer(x._cls, false) << endl
|
|
<< tab(2) << address_of_to_pointer(x._cls, true) << endl
|
|
<< tab(1) << "};" << endl << endl;
|
|
|
|
out << tab(1) << "template <typename D>" << endl
|
|
<< tab(1) << "struct address_const_of" << endl
|
|
<< tab(1) << "{" << endl
|
|
<< tab(2) << address_of_to_pointer(x._cls, true) << endl
|
|
<< tab(1) << "};" << endl;
|
|
|
|
out << comment("@endcond", 1) << endl;
|
|
|
|
return out;
|
|
}
|
|
|
|
struct address_of_inheritance
|
|
{
|
|
eo_class const& _cls;
|
|
std::string _struct_name;
|
|
address_of_inheritance(eo_class const& cls, std::string const& struct_name)
|
|
: _cls(cls), _struct_name(struct_name)
|
|
{}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, address_of_inheritance const& x)
|
|
{
|
|
for (std::string const& parent : x._cls.ancestors)
|
|
{
|
|
out << tab(2) << ", ::" << abstract_namespace << "::" << parent << "::"
|
|
<< x._struct_name << "<" << x._struct_name << ">" << endl;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
struct concrete_address_of
|
|
{
|
|
eo_class const& _cls;
|
|
concrete_address_of(eo_class const& cls) : _cls(cls) {}
|
|
};
|
|
|
|
inline std::ostream&
|
|
operator<<(std::ostream& out, concrete_address_of const& x)
|
|
{
|
|
out << comment("@cond LOCAL", 1);
|
|
std::vector<std::string> names {"address_of", "address_const_of"};
|
|
for (int is_const = 0; is_const != 2; ++is_const)
|
|
{
|
|
std::string const& name = names[is_const];
|
|
|
|
out << tab(1) << "struct " << name << endl
|
|
<< tab(2) << ": " << abstract_full_name(x._cls) << "::"
|
|
<< name << "<" << name << ">" << endl
|
|
<< address_of_inheritance(x._cls, name)
|
|
<< tab(2) << ", ::efl::eo::detail::concrete_" << name << endl
|
|
<< tab(1) << "{" << endl
|
|
<< tab(2) << "explicit " << name << "(" << full_name(x._cls)
|
|
<< (is_const ? " const" : "")
|
|
<< "* p)" << endl
|
|
<< tab(3) << ": ::efl::eo::detail::concrete_" << name << "(p)" << endl
|
|
<< tab(2) << "{}" << endl
|
|
<< tab(1) << "};" << endl
|
|
<< tab(1) << name << " operator&()"
|
|
<< (is_const ? " const" : "")
|
|
<< " { return " << name << "(this); }" << endl << endl;
|
|
}
|
|
out << comment("@endcond", 1) << endl;
|
|
|
|
return out;
|
|
}
|
|
|
|
inline void
|
|
eo_class_declarations_generator(std::ostream& out, eo_class const& cls)
|
|
{
|
|
out << namespace_head(cls)
|
|
<< "struct " << cls.name << ";" << endl << endl
|
|
<< namespace_tail(cls)
|
|
<< comment("@cond EO_CXX_ABSTRACT")
|
|
<< "namespace " << abstract_namespace << " {" << endl << endl
|
|
<< namespace_head(cls)
|
|
<< comment(cls.comment)
|
|
<< "struct " << cls.name << endl
|
|
<< '{' << endl
|
|
<< function_declarations(cls)
|
|
<< events(cls, cls.own_events) << endl
|
|
<< eo_class_getter(cls)
|
|
<< class_implicit_conversion_declaration(cls)
|
|
<< abstract_address_of(cls)
|
|
<< "private:" << endl << endl
|
|
<< concrete_eo_ptr_getter(cls)
|
|
<< "};" << endl << endl
|
|
<< namespace_tail(cls)
|
|
<< "}" << endl
|
|
<< comment("@endcond") << endl
|
|
<< namespace_head(cls)
|
|
<< comment(cls.comment, 0, "@brief Class " + cls.name)
|
|
<< "struct " << cls.name << endl
|
|
<< tab(2) << ": ::efl::eo::concrete" << endl
|
|
<< class_inheritance(cls)
|
|
<< '{' << endl
|
|
<< functors_constructor_methods(cls)
|
|
<< constructor_with_constructor_methods(cls)
|
|
<< constructor_eo(cls)
|
|
<< copy_constructor(cls)
|
|
<< destructor(cls)
|
|
<< constructor_method_function_declarations(cls)
|
|
<< function_declarations(cls)
|
|
<< events(cls, cls.concrete_events) << endl
|
|
<< eo_class_getter(cls)
|
|
<< concrete_address_of(cls)
|
|
<< "private:" << endl << endl
|
|
<< function_call_constructor_methods(cls)
|
|
<< comment("@internal", 1)
|
|
<< tab(1) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
|
|
<< "};" << endl << endl
|
|
<< "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
|
|
<< "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
|
|
<< endl
|
|
<< namespace_tail(cls)
|
|
<< endl;
|
|
}
|
|
|
|
inline void
|
|
eo_class_definitions_generator(std::ostream& out, eo_class const& cls)
|
|
{
|
|
out << constructor_method_function_definitions(cls)
|
|
<< function_definitions(cls, true)
|
|
<< function_definitions(cls, false)
|
|
<< class_implicit_conversion_definition(cls);
|
|
}
|
|
|
|
} } } // namespace efl { namespace eolian { namespace grammar {
|
|
|
|
#endif // EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|