eolian-cxx: Fixed generation of implicit conversion operators
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>
Wed, 15 Jun 2016 18:47:50 +0000 (15:47 -0300)
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>
Wed, 15 Jun 2016 18:50:04 +0000 (15:50 -0300)
src/lib/eolian_cxx/grammar/base_class_definition.hpp
src/lib/eolian_cxx/grammar/class_implementation.hpp

index 99e7d19..c5a22ca 100644 (file)
@@ -13,6 +13,7 @@
 #include "grammar/namespace.hpp"
 #include "grammar/case.hpp"
 #include "grammar/address_of.hpp"
+#include "grammar/attribute_reorder.hpp"
 
 namespace efl { namespace eolian { namespace grammar {
 
@@ -71,14 +72,15 @@ struct base_class_definition_generator
      // operator ::ns::Class_Name() const;
      // operator ::ns::Class_Name&();
      // operator ::ns::Class_Name const&() const;
+     auto class_name = *(lit("::") << lower_case[string]) << "::" << string;
      if(!as_generator
         (
-            scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "() const;\n"
-         << scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "&();\n"
-         << scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << " const&() const;\n"
-         ).generate(sink, std::make_tuple
-                    (cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name)
-                    , context))
+         attribute_reorder<0, 1, 0, 1, 0, 1, 0, 1>
+         (
+            scope_tab << "operator " << class_name << "() const;\n"
+            << scope_tab << "operator " << class_name << "&();\n"
+            << scope_tab << "operator " << class_name << " const&() const;\n"
+         )).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name), context))
        return false;
 
      // /// @cond LOCAL
index de4341f..093d7af 100644 (file)
@@ -22,22 +22,32 @@ struct class_implementation_generator
    template <typename OutputIterator, typename Context>
    bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& ctx) const
    {
+     std::vector<std::string> cpp_namespaces = attributes::cpp_namespaces(cls.namespaces);
+     auto base_class_name = *(lower_case[string] << "::") << string;
+     auto class_name = *(lit("::") << lower_case[string]) << "::" << string;
      return as_generator
        (
         (namespaces
          [*function_definition(get_klass_name(cls))]
-         // << "namespace eo_cxx {\n"
-         // << namespaces
-         // [*function_definition(get_klass_name(cls))]
-         // << "}\n\n"
+         << "\n"
        )).generate(sink, std::make_tuple(cls.namespaces, cls.functions), ctx)
        && as_generator
        (
-        "namespace eo_cxx {\n"
-        << namespaces
-        [*function_definition(get_klass_name(cls))]
-        << "}\n\n"
-       ).generate(sink, std::make_tuple(cls.namespaces, cls.functions), ctx);
+        attribute_reorder<0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3>
+        (
+         "namespace eo_cxx {\n"
+         << namespaces
+         [
+          *function_definition(get_klass_name(cls))
+          << base_class_name << "::operator " << class_name << "() const { return *static_cast< "
+            << class_name << " const*>(static_cast<void const*>(this)); }\n"
+          << base_class_name << "::operator " << class_name << "&() { return *static_cast< "
+            << class_name << "*>(static_cast<void*>(this)); }\n"
+          << base_class_name << "::operator " << class_name << " const&() const { return *static_cast< "
+            << class_name << " const*>(static_cast<void const*>(this)); }\n"
+         ]
+         << "}\n\n"
+         )).generate(sink, std::make_tuple(cls.namespaces, cls.functions, cpp_namespaces, cls.cxx_name), ctx);
    }
 };