/** * src/uml/class_diagram_model.h * * Copyright (c) 2021 Bartek Kryza * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "decorators.h" #include "util/error.h" #include "util/util.h" #include #include #include #include #include #include #include #include #include #include namespace clanguml { namespace model { namespace class_diagram { enum class scope_t { kPublic, kProtected, kPrivate, kNone }; enum class relationship_t { kNone, kExtension, kComposition, kAggregation, kContainment, kOwnership, kAssociation, kInstantiation, kFriendship, kDependency }; std::string to_string(relationship_t r); class stylable_element { public: void set_style(const std::string &style); std::string style() const; private: std::string style_; }; class decorated_element { public: bool skip() const; bool skip_relationship() const; std::pair relationship() const; std::string style_spec(); const std::vector> & decorators() const; void add_decorators( const std::vector> &decorators); private: std::vector> decorators_; }; class class_element : public decorated_element { public: class_element( scope_t scope, const std::string &name, const std::string &type); scope_t scope() const; std::string name() const; std::string type() const; private: scope_t scope_; std::string name_; std::string type_; }; class class_member : public class_element { public: class_member( scope_t scope, const std::string &name, const std::string &type); bool is_relationship() const; void set_is_relationship(bool is_relationship); bool is_static() const; void set_is_static(bool is_static); private: bool is_relationship_{false}; bool is_static_{false}; }; struct method_parameter : public decorated_element { std::string type; std::string name; std::string default_value; std::string to_string( const std::vector &using_namespaces) const; }; class class_method : public class_element { public: class_method( scope_t scope, const std::string &name, const std::string &type); bool is_pure_virtual() const; void set_is_pure_virtual(bool is_pure_virtual); bool is_virtual() const; void set_is_virtual(bool is_virtual); bool is_const() const; void set_is_const(bool is_const); bool is_defaulted() const; void set_is_defaulted(bool is_defaulted); bool is_static() const; void set_is_static(bool is_static); const std::vector ¶meters() const; void add_parameter(method_parameter &¶meter); private: std::vector parameters_; bool is_pure_virtual_{false}; bool is_virtual_{false}; bool is_const_{false}; bool is_defaulted_{false}; bool is_static_{false}; }; struct class_parent { enum class access_t { kPublic, kProtected, kPrivate }; std::string name; bool is_virtual{false}; access_t access; }; struct class_relationship : public decorated_element, public stylable_element { relationship_t type{relationship_t::kAssociation}; std::string destination; std::string multiplicity_source; std::string multiplicity_destination; std::string label; scope_t scope{scope_t::kNone}; friend bool operator==( const class_relationship &l, const class_relationship &r); }; struct class_template { std::string name; std::string type; std::string default_value; bool is_variadic{false}; friend bool operator==(const class_template &l, const class_template &r); }; class element : public decorated_element { public: element(const std::vector &using_namespaces); std::string alias() const; void set_name(const std::string &name) { name_ = name; } std::string name() const { return name_; } void set_namespace(const std::vector &ns) { namespace_ = ns; } std::vector get_namespace() const { return namespace_; } virtual std::string full_name(bool relative) const { return name(); } void set_using_namespaces(const std::vector &un); const std::vector &using_namespaces() const; std::vector &relationships(); const std::vector &relationships() const; void add_relationship(class_relationship &&cr); protected: const uint64_t m_id{0}; private: std::string name_; std::vector namespace_; std::vector using_namespaces_; std::vector relationships_; static std::atomic_uint64_t m_nextId; }; struct type_alias { std::string alias; std::string underlying_type; }; class class_ : public element, public stylable_element { public: class_(const std::vector &using_namespaces); bool is_struct() const; void set_is_struct(bool is_struct); bool is_template() const; void set_is_template(bool is_template); bool is_template_instantiation() const; void set_is_template_instantiation(bool is_template_instantiation); void add_member(class_member &&member); void add_method(class_method &&method); void add_parent(class_parent &&parent); void add_template(class_template &&tmplt); const std::vector &members() const; const std::vector &methods() const; const std::vector &parents() const; const std::vector &templates() const; void set_base_template(const std::string &full_name); std::string base_template() const; friend bool operator==(const class_ &l, const class_ &r); void add_type_alias(type_alias &&ta); std::string full_name(bool relative = true) const override; bool is_abstract() const; private: bool is_struct_{false}; bool is_template_{false}; bool is_template_instantiation_{false}; std::vector members_; std::vector methods_; std::vector bases_; std::vector templates_; std::string base_template_full_name_; std::map type_aliases_; std::string full_name_; }; struct enum_ : public element, public stylable_element { public: enum_(const std::vector &using_namespaces); friend bool operator==(const enum_ &l, const enum_ &r); std::string full_name(bool relative = true) const override; std::vector &constants(); const std::vector &constants() const; private: std::vector constants_; }; class diagram { public: std::string name() const; void set_name(const std::string &name); const std::vector classes() const; const std::vector enums() const; bool has_class(const class_ &c) const; void add_type_alias(type_alias &&ta); void add_class(class_ &&c); void add_enum(enum_ &&e); std::string to_alias(const std::string &full_name) const; private: std::string name_; std::vector classes_; std::vector enums_; std::map type_aliases_; }; } } }