Refactored package_trait iterators

This commit is contained in:
Bartek Kryza
2022-02-17 19:51:37 +01:00
parent 8951e7f28c
commit 2ff7de1d85
5 changed files with 49 additions and 29 deletions

View File

@@ -159,7 +159,7 @@ DiagramModel generate(cppast::libclang_compilation_database &db,
for (auto &file : parser.files()) for (auto &file : parser.files())
ctx(file); ctx(file);
return d; return std::move(d);
} }
} }

View File

@@ -30,6 +30,8 @@ generator::generator(diagram_config &config, diagram_model &model)
void generator::generate_relationships( void generator::generate_relationships(
const package &p, std::ostream &ostr) const const package &p, std::ostream &ostr) const
{ {
LOG_DBG("Generating relationships for package {}", p.full_name(true));
const auto &uns = m_config.using_namespace(); const auto &uns = m_config.using_namespace();
// Generate this packages relationship // Generate this packages relationship
@@ -52,13 +54,15 @@ void generator::generate_relationships(
} }
// Process it's subpackages relationships // Process it's subpackages relationships
for (auto subpackage = p.cbegin(); subpackage != p.cend(); subpackage++) { for (const std::unique_ptr<package> &subpackage : p) {
generate_relationships(**subpackage, ostr); generate_relationships(*subpackage, ostr);
} }
} }
void generator::generate(const package &p, std::ostream &ostr) const void generator::generate(const package &p, std::ostream &ostr) const
{ {
LOG_DBG("Generating package {}", p.name());
const auto &uns = m_config.using_namespace(); const auto &uns = m_config.using_namespace();
ostr << "package [" << p.name() << "] "; ostr << "package [" << p.name() << "] ";
@@ -72,10 +76,8 @@ void generator::generate(const package &p, std::ostream &ostr) const
ostr << " {" << '\n'; ostr << " {" << '\n';
// C++17 cannot figure out to use cbegin/cend in a for-range loop on const for (const auto &subpackage : p) {
// collection... ¯\_(ツ)_/¯ generate(*subpackage, ostr);
for (auto subpackage = p.cbegin(); subpackage != p.cend(); subpackage++) {
generate(**subpackage, ostr);
} }
ostr << "}" << '\n'; ostr << "}" << '\n';
@@ -108,5 +110,4 @@ void generator::generate(std::ostream &ostr) const
ostr << "@enduml" << '\n'; ostr << "@enduml" << '\n';
} }
} }

View File

@@ -28,11 +28,16 @@
namespace clanguml::package_diagram::model { namespace clanguml::package_diagram::model {
class diagram : public clanguml::common::model::diagram, class diagram : public clanguml::common::model::diagram,
public detail::package_trait<package, std::vector> { public detail::package_trait<package> {
public: public:
std::string to_alias(const std::string &full_name) const; diagram() = default;
private: diagram(const diagram &) = delete;
std::vector<std::unique_ptr<package>> packages_; diagram(diagram &&) = default;
diagram &operator=(const diagram &) = delete;
diagram &operator=(diagram &&) = default;
std::string to_alias(const std::string &full_name) const;
}; };
} }

View File

@@ -31,10 +31,18 @@
namespace clanguml::package_diagram::model { namespace clanguml::package_diagram::model {
namespace detail { namespace detail {
template <typename T, template <typename, typename> class Container, template <typename T> class package_trait {
typename Ptr = std::unique_ptr<T>>
class package_trait {
public: public:
package_trait() = default;
package_trait(const package_trait &) = delete;
package_trait(package_trait &&) = default;
package_trait &operator=(const package_trait &) = delete;
package_trait &operator=(package_trait &&) = default;
virtual ~package_trait() = default;
void add_package(std::unique_ptr<T> p) void add_package(std::unique_ptr<T> p)
{ {
auto it = std::find_if(packages_.begin(), packages_.end(), auto it = std::find_if(packages_.begin(), packages_.end(),
@@ -73,8 +81,11 @@ public:
{ {
LOG_DBG("Getting package at path: {}", fmt::join(path, "::")); LOG_DBG("Getting package at path: {}", fmt::join(path, "::"));
if (path.empty() || !has_package(path.at(0))) if (path.empty() || !has_package(path.at(0))) {
LOG_WARN(
"Sub package {} not found in package", fmt::join(path, "::"));
return {}; return {};
}
auto p = get_package(path.at(0)); auto p = get_package(path.at(0));
if (path.size() == 1) if (path.size() == 1)
@@ -104,26 +115,31 @@ public:
packages_.end(); packages_.end();
} }
typedef typename Container<Ptr, std::allocator<Ptr>>::iterator iterator; auto begin() { return packages_.begin(); }
typedef typename Container<Ptr, std::allocator<Ptr>>::const_iterator auto end() { return packages_.end(); }
const_iterator;
inline iterator begin() noexcept { return packages_.begin(); } auto cbegin() const { return packages_.cbegin(); }
inline const_iterator cbegin() const noexcept { return packages_.cbegin(); } auto cend() const { return packages_.cend(); }
inline iterator end() noexcept { return packages_.end(); }
inline const_iterator cend() const noexcept { return packages_.cend(); }
protected: auto begin() const { return packages_.begin(); }
Container<Ptr, std::allocator<Ptr>> packages_; auto end() const { return packages_.end(); }
private:
std::vector<std::unique_ptr<T>> packages_;
}; };
} }
class package : public common::model::element, class package : public common::model::element,
public common::model::stylable_element, public common::model::stylable_element,
public detail::package_trait<package, std::vector> { public detail::package_trait<package> {
public: public:
package(const std::vector<std::string> &using_namespaces); package(const std::vector<std::string> &using_namespaces);
package(const package &) = delete;
package(package &&) = default;
package &operator=(const package &) = delete;
std::string full_name(bool relative) const override; std::string full_name(bool relative) const override;
friend bool operator==(const package &l, const package &r); friend bool operator==(const package &l, const package &r);

View File

@@ -82,11 +82,9 @@ clanguml::package_diagram::model::diagram generate_package_diagram(
using diagram_visitor = using diagram_visitor =
clanguml::package_diagram::visitor::translation_unit_visitor; clanguml::package_diagram::visitor::translation_unit_visitor;
auto model = clanguml::common::generators::plantuml::generate<diagram_model, return clanguml::common::generators::plantuml::generate<diagram_model,
diagram_config, diagram_visitor>( diagram_config, diagram_visitor>(
db, diagram->name, dynamic_cast<diagram_config &>(*diagram)); db, diagram->name, dynamic_cast<diagram_config &>(*diagram));
return model;
} }
std::string generate_sequence_puml( std::string generate_sequence_puml(