void inserter_implementation_helper_stitch(
    formatters::entity_formatting_assistant& fa,
    const formattables::class_info& c,
    const bool inside_class) {

    if (c.requires_stream_manipulators()) {
fa.stream() << "    boost::io::ios_flags_saver ifs(s);" << std::endl;
fa.stream() << "    s.setf(std::ios_base::boolalpha);" << std::endl;
fa.stream() << "    s.setf(std::ios::fixed, std::ios::floatfield);" << std::endl;
fa.stream() << "    s.precision(6);" << std::endl;
fa.stream() << "    s.setf(std::ios::showpoint);" << std::endl;
fa.stream() << std::endl;
    }

    const bool no_parents_and_no_properties(c.parents().empty() &&
        c.all_properties().empty());
fa.stream() << "    s << \" { \"" << std::endl;
fa.stream() << "      << \"\\\"__type__\\\": \" << \"\\\"" << c.qualified_name() << "\\\"\"" << (no_parents_and_no_properties ? " << \" }\";" : " << \", \"") << std::endl;

    dogen::formatters::sequence_formatter sf(c.parents().size());
    sf.prefix_configuration().first("  << ").not_first("s << ");
    sf.element_separator("");
    for (const auto p : c.parents()) {
fa.stream() << "    " << sf.prefix() << "\"\\\"__parent_" << sf.current_position() << "__\\\": \"" << sf.postfix() << ";" << std::endl;
fa.stream() << "    " << p.name() << "::to_stream(s);" << std::endl;
        sf.next();
    }

    auto ntfa(fa.make_nested_type_formatting_assistant());
    sf.reset(c.properties().size());

    if (!c.parents().empty())
        sf.prefix_configuration().first("s << \", \"\n      ");
    else
        sf.prefix_configuration().first("  ");
    sf.prefix_configuration().not_first("  ");
    sf.postfix_configuration().not_last(" << \", \"");
    sf.element_separator("");

    for (const auto p : c.properties()) {
        std::string variable_name;
        if (inside_class)
            variable_name = fa.make_member_variable_name(p);
        else
            variable_name = "v." + fa.make_getter_setter_name(p) + "()";

fa.stream() << "    " << sf.prefix() << "<< \"\\\"" << p.name() << "\\\": \" << " << ntfa.streaming_for_type(p.type(), variable_name) << sf.postfix() << std::endl;
        sf.next();
    }

    if (!no_parents_and_no_properties) {
        if (!c.properties().empty())
fa.stream() << "      << \" }\";" << std::endl;
        else
fa.stream() << "    s << \" }\";" << std::endl;
    }

    if (!inside_class)
fa.stream() << "    return(s);" << std::endl;
}
dogen::formatters::file class_header_formatter_stitch(
    assistant& a, const formattables::class_info& c) {

    {
        auto sbf(a.make_scoped_boilerplate_formatter());
        const auto odbs(a.get_odb_settings());
        if (!odbs || odbs->pragmas().empty()) {
a.stream() << "// class has no ODB pragmas defined." << std::endl;
a.stream() << std::endl;
        } else {
            {
                auto snf(a.make_scoped_namespace_formatter(c.namespaces()));

a.stream() << std::endl;
a.stream() << "#ifdef ODB_COMPILER" << std::endl;
a.stream() << std::endl;
                const std::string odb_key("odb_pragma");
                for (const auto& pg : odbs->pragmas())
a.stream() << "#pragma db object(" << c.name() << ") " << pg << std::endl;

                bool is_first(true);
                for (const auto p : c.properties()) {
                    const auto podbs(a.get_odb_settings(p.id()));
                    if (podbs) {
                        for (const auto pg : podbs->pragmas()) {
                            if (is_first)
a.stream() << std::endl;
                            is_first = false;
a.stream() << "#pragma db member(" << c.name() << "::" << a.make_member_variable_name(p) << ") " << pg << std::endl;
                        }
                    }
                }
a.stream() << std::endl;
a.stream() << "#endif" << std::endl;
a.stream() << std::endl;
            }
a.stream() << std::endl;
        }
    } // sbf
    return a.make_file();
}
dogen::formatters::file class_implementation_formatter_stitch(
    assistant& a, const formattables::class_info& c) {

    {
        auto sbf(a.make_scoped_boilerplate_formatter());
        a.add_helper_methods(c);

        {
            auto snf(a.make_scoped_namespace_formatter(c.namespaces()));
            const bool no_arg(!c.is_parent() && c.parents().empty() &&
                c.properties().empty());
a.stream() << std::endl;
a.stream() << "std::ostream& operator<<(std::ostream& s, const " << c.name() << "&" << (no_arg ? "" : " v") << ") {" << std::endl;
            if (c.is_parent() || !c.parents().empty()) {
a.stream() << "    v.to_stream(s);" << std::endl;
a.stream() << "    return(s);" << std::endl;
            } else
                io::inserter_implementation_helper_stitch(a, c, false/*inside_class*/);
a.stream() << "}" << std::endl;
a.stream() << std::endl;
        } // snf
    } // sbf
    return a.make_file();
}
示例#4
0
void dispatcher::visit(const formattables::class_info& c) {
    const bool empty_out_content(
        c.generation_type() == yarn::generation_types::partial_generation);
    for (const auto f : container_.class_formatters())
        format_entity(*f, c, empty_out_content);
}
dogen::formatters::file class_implementation_formatter_stitch(
    formatters::entity_formatting_assistant& fa,
    const formattables::class_info& c) {

    {
        auto sbf(fa.make_scoped_boilerplate_formatter());
        if (!c.properties().empty()) {
fa.stream() << "namespace {" << std::endl;
        fa.add_helper_methods();
fa.stream() << std::endl;
fa.stream() << "}" << std::endl;
fa.stream() << std::endl;
        }

        {
            auto snf(fa.make_scoped_namespace_formatter());

            /*
             * Default constructor.
             */
            if (!c.is_parent()) {
fa.stream() << std::endl;
fa.stream() << c.name() << "_generator::" << c.name() << "_generator() : position_(0) { }" << std::endl;
            }

            /*
             * Populate method.
             */
            if (!c.is_immutable()) {
                bool no_args(c.properties().empty() && c.parents().empty());
                if (no_args) {
fa.stream() << std::endl;
fa.stream() << "void " << c.name() << "_generator::" << std::endl;
fa.stream() << "populate(const unsigned int /*position*/, result_type& /*v*/) {" << std::endl;
                } else {
fa.stream() << std::endl;
fa.stream() << "void " << c.name() << "_generator::" << std::endl;
fa.stream() << "populate(const unsigned int position, result_type& v) {" << std::endl;
                }

                for (const auto p : c.parents()) {
fa.stream() << "    " << p.qualified_name() << "_generator::populate(position, v);" << std::endl;
                }
                unsigned int i(0);
                for (const auto p : c.properties()) {
fa.stream() << "    v." << p.name() << "(create_" << p.type().complete_identifiable_name() << "(position + " << i << "));" << std::endl;
                    ++i;
                }
fa.stream() << "}" << std::endl;
            }

            /*
             * Create method.
             */
            if (!c.is_parent()) {
                 const bool no_arg(c.all_properties().empty());
fa.stream() << std::endl;
fa.stream() << c.name() << "_generator::result_type" << std::endl;
fa.stream() << c.name() << "_generator::create(const unsigned int" << (no_arg ? "/*position*/" : " position") << ") {" << std::endl;
                if (c.is_immutable()) {
fa.stream() << "    return " << c.name() << "(" << std::endl;
                    // FIXME: hack
                    if (c.properties().empty())
fa.stream() << std::endl;
                    else {
                        dogen::formatters::sequence_formatter sf(c.properties().size());
                        for (const auto p : c.properties()) {
fa.stream() << "        create_" << p.type().complete_identifiable_name() << "(position + " << sf.current_position() << ")" << sf.postfix() << std::endl;
                            sf.next();
                        }
                    }
fa.stream() << "        );" << std::endl;
                } else {
fa.stream() << "    " << c.name() << " r;" << std::endl;
                    if (!c.all_properties().empty())
fa.stream() << "    " << c.name() << "_generator::populate(position, r);" << std::endl;
fa.stream() << "    return r;" << std::endl;
                }
fa.stream() << "}" << std::endl;
            }

            /*
             * Create method ptr.
             */
fa.stream() << std::endl;
fa.stream() << c.name() << "_generator::result_type*" << std::endl;
fa.stream() << c.name() << "_generator::create_ptr(const unsigned int position) {" << std::endl;
            if (c.leaves().empty()) {
                if (c.is_immutable())
fa.stream() << "    return new " << c.name() << "(create(position));" << std::endl;
                else {
fa.stream() << "    " << c.name() << "* p = new " << c.name() << "();" << std::endl;
fa.stream() << "    " << c.name() << "_generator::populate(position, *p);" << std::endl;
fa.stream() << "    return p;" << std::endl;
                }
            } else {
                auto leaves(c.leaves());
                const auto front(leaves.front());
                leaves.pop_front();
                unsigned int i(0);
                unsigned int total(leaves.size());
                for (const auto l : leaves) {
fa.stream() << "    if ((position % " << total << ") == " << i++ << ")" << std::endl;
fa.stream() << "        return " << l << "_generator::create_ptr(position);" << std::endl;
                }
fa.stream() << "    return " << front << "_generator::create_ptr(position);" << std::endl;
            }
fa.stream() << "}" << std::endl;
            /*
             * Function operator
             */
             if (!c.is_parent()) {
fa.stream() << std::endl;
fa.stream() << c.name() << "_generator::result_type" << std::endl;
fa.stream() << c.name() << "_generator::operator()() {" << std::endl;
fa.stream() << "    return create(position_++);" << std::endl;
fa.stream() << "}" << std::endl;
            }
fa.stream() << std::endl;
        } // snf
    } // sbf
    return fa.make_file();
}
dogen::formatters::file class_header_formatter_stitch(
    formatters::entity_formatting_assistant& fa,
    const formattables::class_info& c) {

    {
        auto sbf(fa.make_scoped_boilerplate_formatter());
        {
            auto snf(fa.make_scoped_namespace_formatter());
            fa.stream() << std::endl;
            fa.comment(c.documentation());
            if (c.parents().empty()) {
                fa.stream() << "class " << c.name() << " " << fa.make_final_keyword_text(c) << "{" << std::endl;
            } else if (c.parents().size() == 1) {
                fa.stream() << "class " << c.name() << " " << fa.make_final_keyword_text(c) << ": public " << c.parents().front().qualified_name() << " {" << std::endl;
            } else {
                dogen::formatters::sequence_formatter sf(c.parents().size());
                for (const auto p : c.parents()) {
                    fa.stream() << "    public " << p.qualified_name() << sf.postfix() << std::endl;
                    sf.next();
                }
            }
            fa.stream() << "public:" << std::endl;
            /*
             * Compiler generated constructors and destructors.
             */
            if (!c.requires_manual_default_constructor())
                fa.stream() << "    " << c.name() << "() = default;" << std::endl;
            fa.stream() << "    " << c.name() << "(const " << c.name() << "&) = default;" << std::endl;
            if (!c.requires_manual_move_constructor())
                fa.stream() << "    " << c.name() << "(" << c.name() << "&&) = default;" << std::endl;
            if (!c.is_parent() && c.parents().empty())
                fa.stream() << "    ~" << c.name() << "() = default;" << std::endl;
            if (c.is_immutable())
                fa.stream() << "    " << c.name() << "& operator=(const " << c.name() << "&) = delete;" << std::endl;
            else if (c.all_properties().empty())
                fa.stream() << "    " << c.name() << "& operator=(const " << c.name() << "&) = default;" << std::endl;
            fa.stream() << std::endl;
            /*
             * Manually generated default constructor.
             */
            if (c.requires_manual_default_constructor()) {
                fa.stream() << "public:" << std::endl;
                fa.stream() << "    " << c.name() << "();" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Manually generated destructor.
             *
             * according to MEC++, item 33, base classes should always be
             * abstract. this avoids all sorts of tricky problems with
             * assignment and swap.
             *
             * incidentally, this also fixes some strange clang errors:
             * undefined reference to `vtable.
             */
            if (c.is_parent()) {
                fa.stream() << "    virtual ~" << c.name() << "() noexcept = 0;" << std::endl;
                fa.stream() << std::endl;
            } else if (c.parents().size() != 0) {
                fa.stream() << "    virtual ~" << c.name() << "() noexcept { }" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Manually generated move constructor.
             */
            if (c.requires_manual_move_constructor()) {
                fa.stream() << "public:" << std::endl;
                fa.stream() << "    " << c.name() << "(" << c.name() << "&& rhs);" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Manually generated complete constructor.
             */
            if (!fa.is_complete_constructor_disabled() && !c.all_properties().empty()) {
                fa.stream() << "public:" << std::endl;
                const auto prop_count(c.all_properties().size());
                if (prop_count == 1) {
                    const auto p(*c.all_properties().begin());
                    fa.stream() << "    explicit " << c.name() << "(const " << p.type().complete_name() << fa.make_by_ref_text(p) << " " << p.name() << ");" << std::endl;
                } else {
                    fa.stream() << "    " << c.name() << "(" << std::endl;
                    dogen::formatters::sequence_formatter sf(prop_count);
                    sf.postfix_configuration().last(");");
                    for (const auto& p : c.all_properties()) {
                        fa.stream() << "        const " << p.type().complete_name() << fa.make_by_ref_text(p) << " " << p.name() << sf.postfix() << std::endl;
                        sf.next();
                    }
                }
                fa.stream() << std::endl;
            }

            /*
             * Friends
             */
            if (fa.is_serialization_enabled()) {
                fa.stream() << "private:" << std::endl;
                fa.stream() << "    template<typename Archive>" << std::endl;
                fa.stream() << "    friend void boost::serialization::save(Archive& ar, const " << c.name() << "& v, unsigned int version);" << std::endl;
                fa.stream() << std::endl;
                fa.stream() << "    template<typename Archive>" << std::endl;
                fa.stream() << "    friend void boost::serialization::load(Archive& ar, " << c.name() << "& v, unsigned int version);" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Visitation.
             */
            if (c.is_visitable()) {
                fa.stream() << "public:" << std::endl;
                fa.stream() << "    virtual void accept(const " << c.name() << "_visitor& v) const = 0;" << std::endl;
                fa.stream() << "    virtual void accept(" << c.name() << "_visitor& v) const = 0;" << std::endl;
                fa.stream() << "    virtual void accept(const " << c.name() << "_visitor& v) = 0;" << std::endl;
                fa.stream() << "    virtual void accept(" << c.name() << "_visitor& v) = 0;" << std::endl;
                fa.stream() << std::endl;
            } else if (c.is_original_parent_visitable() && !c.is_parent()) {
                fa.stream() << "public:" << std::endl;
                fa.stream() << "    virtual void accept(const " << c.original_parent_name() << "_visitor& v) const override {" << std::endl;
                fa.stream() << "        v.visit(*this);" << std::endl;
                fa.stream() << "    }" << std::endl;
                fa.stream() << std::endl;
                fa.stream() << "    virtual void accept(" << c.original_parent_name() << "_visitor& v) const override {" << std::endl;
                fa.stream() << "        v.visit(*this);" << std::endl;
                fa.stream() << "    }" << std::endl;
                fa.stream() << std::endl;
                fa.stream() << "    virtual void accept(const " << c.original_parent_name() << "_visitor& v) override {" << std::endl;
                fa.stream() << "        v.visit(*this);" << std::endl;
                fa.stream() << "    }" << std::endl;
                fa.stream() << std::endl;
                fa.stream() << "    virtual void accept(" << c.original_parent_name() << "_visitor& v) override {" << std::endl;
                fa.stream() << "        v.visit(*this);" << std::endl;
                fa.stream() << "    }" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Streaming
             */
            if (fa.is_io_enabled()) {
                if (c.is_parent()) {
                    fa.stream() << "public:" << std::endl;
                    fa.stream() << "    virtual void to_stream(std::ostream& s) const;" << std::endl;
                    fa.stream() << std::endl;
                } else if (!c.parents().empty()) {
                    fa.stream() << "public:" << std::endl;
                    fa.stream() << "    void to_stream(std::ostream& s) const override;" << std::endl;
                    fa.stream() << std::endl;
                }
            }

            /*
             * Getters and setters.
             */
            if (!c.properties().empty()) {
                fa.stream() << "public:" << std::endl;
                for (const auto p : c.properties()) {
                    fa.comment_start_method_group(p.documentation(), !p.is_immutable());

                    if (p.type().is_primitive() || p.type().is_enumeration()) {
                        fa.stream() << "    " << p.type().complete_name() << " " << p.name() << "() const;" << std::endl;
                        if (p.is_immutable()) {
                            fa.stream() << std::endl;
                            continue;
                        }
                        fa.stream() << "    " << fa.make_setter_return_type(c.name(), p) << " " << p.name() << "(const " << p.type().complete_name() << fa.make_by_ref_text(p) << " v);" << std::endl;
                    } else {
                        fa.stream() << "    const " << p.type().complete_name() << "& " << p.name() << "() const;" << std::endl;
                        if (p.is_immutable()) {
                            fa.stream() << std::endl;
                            continue;
                        }
                        fa.stream() << "    " << p.type().complete_name() << fa.make_by_ref_text(p) << " " << p.name() << "();" << std::endl;
                        fa.stream() << "    " << fa.make_setter_return_type(c.name(), p) << " " << p.name() << "(const " << p.type().complete_name() << fa.make_by_ref_text(p) << " v);" << std::endl;
                        fa.stream() << "    " << fa.make_setter_return_type(c.name(), p) << " " << p.name() << "(const " << p.type().complete_name() << "&& v);" << std::endl;
                    }
                    fa.comment_end_method_group(p.documentation(), !p.is_immutable());
                    fa.stream() << std::endl;
                }
            }

            /*
             * Equality.
             *
             * Equality is only public in leaf classes - MEC++-33.
             */
            if (c.is_parent()) {
                fa.stream() << "protected:" << std::endl;
                fa.stream() << "    bool compare(const " << c.name() << "& rhs) const;" << std::endl;
            } else {
                fa.stream() << "public:" << std::endl;
                fa.stream() << "    bool operator==(const " << c.name() << "& rhs) const;" << std::endl;
                fa.stream() << "    bool operator!=(const " << c.name() << "& rhs) const {" << std::endl;
                fa.stream() << "        return !this->operator==(rhs);" << std::endl;
                fa.stream() << "    }" << std::endl;
                fa.stream() << std::endl;
            }

            if (c.is_parent() || !c.parents().empty()) {
                fa.stream() << "public:" << std::endl;
                if (c.is_parent() && c.parents().empty()) {
                    fa.stream() << "    virtual bool equals(const " << c.name() << "& other) const = 0;" << std::endl;
                } else if (c.is_parent()) {
                    fa.stream() << "    virtual bool equals(const " << c.original_parent_name_qualified() << "& other) const = 0;" << std::endl;
                } else if (!c.parents().empty()) {
                    fa.stream() << "    bool equals(const " << c.original_parent_name_qualified() << "& other) const override;" << std::endl;
                }
                fa.stream() << std::endl;
            }

            /*
             * Swap and assignment.
             *
             * Swap and assignment are only public in leaf classes - MEC++-33
             */
            if ((!c.all_properties().empty() || c.is_parent()) && !c.is_immutable()) {
                if (c.is_parent()) {
                    fa.stream() << "protected:" << std::endl;
                } else {
                    fa.stream() << "public:" << std::endl;
                }
                fa.stream() << "    void swap(" << c.name() << "& other) noexcept;" << std::endl;
                if (!c.is_parent() && !c.is_immutable()) {
                    fa.stream() << "    " << c.name() << "& operator=(" << c.name() << " other);" << std::endl;
                }
                fa.stream() << std::endl;
            }

            /*
             * Member variables.
             */
            if (!c.properties().empty()) {
                fa.stream() << "private:" << std::endl;
                for (const auto& p : c.properties()) {
                    fa.stream() << "    " << p.type().complete_name() << " " << fa.make_member_variable_name(p) << ";" << std::endl;
                }
            }
            fa.stream() << "};" << std::endl;
            fa.stream() << std::endl;
            /*
             * Destructor implementation.
             */
            if (c.is_parent()) {
                fa.stream() << "inline " << c.name() << "::~" << c.name() << "() noexcept { }" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Global inserter operator implementation
             */
            if (fa.is_io_enabled() && fa.is_io_integrated()) {
                fa.stream() << "    std::ostream& operator<<(std::ostream& s, const " << c.name() << "& v);" << std::endl;
                fa.stream() << std::endl;
            }

            /*
             * Global equality operator implementation.
             */
            if (c.is_parent()) {
                fa.stream() << "inline bool operator==(const " << c.name() << "& lhs, const " << c.name() << "& rhs) {" << std::endl;
                fa.stream() << "    return lhs.equals(rhs);" << std::endl;
                fa.stream() << "}" << std::endl;
                fa.stream() << std::endl;
            }
        }

        if (!c.all_properties().empty() && !c.is_parent() && !c.is_immutable()) {
            fa.stream() << std::endl;
            fa.stream() << "namespace std {" << std::endl;
            fa.stream() << std::endl;
            fa.stream() << "template<>" << std::endl;
            fa.stream() << "inline void swap(" << std::endl;
            fa.stream() << "    " << c.qualified_name() << "& lhs," << std::endl;
            fa.stream() << "    " << c.qualified_name() << "& rhs) {" << std::endl;
            fa.stream() << "    lhs.swap(rhs);" << std::endl;
            fa.stream() << "}" << std::endl;
            fa.stream() << std::endl;
            fa.stream() << "}" << std::endl;
        } // snf
        fa.stream() << std::endl;
    } // sbf
    return fa.make_file();
}