diff --git a/libs/indexer/ftypes_subtypes.hpp b/libs/indexer/ftypes_subtypes.hpp index b50032600..57a54071b 100644 --- a/libs/indexer/ftypes_subtypes.hpp +++ b/libs/indexer/ftypes_subtypes.hpp @@ -1,122 +1,123 @@ #pragma once +#include #include +#include +#include +#include #include #include namespace ftypes { - using namespace std; +using namespace std; - class Subtypes +class Subtypes +{ +public: + /// Static instance + static Subtypes const & Instance(); + + /** + * Checks if the given type is a type with subtypes or a subtype + * @param type The type to check + * @return `true` if it is a type with subtypes or a subtype, otherwise `false` + */ + bool IsTypeWithSubtypesOrSubtype(uint32_t const type) const { return IsTypeWithSubtypes(type) || IsSubtype(type); } + + /** + * Checks if the given type is a type with subtypes + * @param type The type to check + * @return `true` if it is a type with subtypes, otherwise `false` + */ + bool IsTypeWithSubtypes(uint32_t const type) const { - public: - /// Static instance - static Subtypes const & Instance(); + return ranges::find(m_types.begin(), m_types.end(), type) != m_types.end(); + } - /** - * Checks if the given type is a type with subtypes or a subtype - * @param type The type to check - * @return `true` if it is a type with subtypes or a subtype, otherwise `false` - */ - bool IsTypeWithSubtypesOrSubtype(uint32_t const type) const + /** + * Checks if the given type is a subtype + * @param type The type to check + * @return `true` if it is a subtype, otherwise `false` + */ + bool IsSubtype(uint32_t const type) const + { + return ranges::find(m_subtypes.begin(), m_subtypes.end(), type) != m_subtypes.end(); + } + + /** + * Checks if the given type is a subtype of a given parent type + * @param type The type to check + * @param parentType The possible parent type + * @return `true` if it is a subtype of the parent type, otherwise `false` + */ + bool IsSubtypeOfParentType(uint32_t const type, uint32_t const parentType) const + { + auto position = m_typesWithSubtypes.find(parentType); + if (position != m_typesWithSubtypes.end()) { - return IsTypeWithSubtypes(type) || IsSubtype(type); + vector subtypes = position->second; + return ranges::find(subtypes.begin(), subtypes.end(), type) != subtypes.end(); } - /** - * Checks if the given type is a type with subtypes - * @param type The type to check - * @return `true` if it is a type with subtypes, otherwise `false` - */ - bool IsTypeWithSubtypes(uint32_t const type) const - { - return find(m_types.begin(), m_types.end(), type) != m_types.end(); - } - - /** - * Checks if the given type is a subtype - * @param type The type to check - * @return `true` if it is a subtype, otherwise `false` - */ - bool IsSubtype(uint32_t const type) const - { - return find(m_subtypes.begin(), m_subtypes.end(), type) != m_subtypes.end(); - } - - /** - * Checks if the given type is a subtype of a given parent type - * @param type The type to check - * @param parentType The possible parent type - * @return `true` if it is a subtype of the parent type, otherwise `false` - */ - bool IsSubtypeOfParentType(uint32_t const type, uint32_t const parentType) const - { - auto position = m_typesWithSubtypes.find(parentType); - if (position != m_typesWithSubtypes.end()) { - vector subtypes = position->second; - return find(subtypes.begin(), subtypes.end(), type) != subtypes.end(); - } - - return false; - } - - /** - * Compares to given types based on their type relation - * @param firstType The first type to compare - * @param secondType The type to compare - * @return `true` if the first type is a subtype but the second one isn't, `false` if it is the other way around - */ - optional ComaprisonResultBasedOnTypeRelation(uint32_t const firstType, uint32_t const secondType) const - { - bool const firstTypeIsSubtype = IsSubtype(firstType); - bool const secondTypeIsSubtype = IsSubtype(secondType); - if (!firstTypeIsSubtype && !secondTypeIsSubtype) - return {}; - else if (firstTypeIsSubtype && !secondTypeIsSubtype) - return false; - else if (!firstTypeIsSubtype && secondTypeIsSubtype) - return true; - - // If they got to here, both are subtypes. So use the order of the subtypes for the comparison. - for (auto [types, subtypes] : m_typesWithSubtypes) - { - for (auto const subtype : subtypes) - { - if (subtype == firstType) - return true; - else if (subtype == secondType) - return false; - } - } + return false; + } + /** + * Compares to given types based on their type relation + * @param firstType The first type to compare + * @param secondType The type to compare + * @return `true` if the first type is a subtype but the second one isn't, `false` if it is the other way around + */ + optional ComaprisonResultBasedOnTypeRelation(uint32_t const firstType, uint32_t const secondType) const + { + bool const firstTypeIsSubtype = IsSubtype(firstType); + bool const secondTypeIsSubtype = IsSubtype(secondType); + if (!firstTypeIsSubtype && !secondTypeIsSubtype) return {}; - } + else if (firstTypeIsSubtype && !secondTypeIsSubtype) + return false; + else if (!firstTypeIsSubtype && secondTypeIsSubtype) + return true; - /** - * Checks if the given type path belongs to a type with subtypes or a subtype - * @param typePath The type path to check - * @return `true` if it is a type with subtypes or a subtype, otherwise `false` - */ - bool IsPathOfTypeWithSubtypesOrSubtype(vector const typePath) const + // If they got to here, both are subtypes. So use the order of the subtypes for the comparison. + for (auto [types, subtypes] : m_typesWithSubtypes) { - return find(m_typesAndSubtypesPaths.begin(), m_typesAndSubtypesPaths.end(), typePath) != m_typesAndSubtypesPaths.end(); + for (auto const subtype : subtypes) + if (subtype == firstType) + return true; + else if (subtype == secondType) + return false; } - private: - /// Constructor - Subtypes(); + return {}; + } - /// Types, which have subtypes, as unordered set for faster check performance - unordered_set m_types; + /** + * Checks if the given type path belongs to a type with subtypes or a subtype + * @param typePath The type path to check + * @return `true` if it is a type with subtypes or a subtype, otherwise `false` + */ + bool IsPathOfTypeWithSubtypesOrSubtype(vector const typePath) const + { + return ranges::find(m_typesAndSubtypesPaths.begin(), m_typesAndSubtypesPaths.end(), typePath) != + m_typesAndSubtypesPaths.end(); + } - /// Subypes as unordered set for faster check performance - unordered_set m_subtypes; +private: + /// Constructor + Subtypes(); - /// Types with their associated subtypes - map> m_typesWithSubtypes; + /// Types, which have subtypes, as unordered set for faster check performance + unordered_set m_types; - /// Paths of types, which have subtypes, and subtypes for the generator - vector> m_typesAndSubtypesPaths; - }; + /// Subypes as unordered set for faster check performance + unordered_set m_subtypes; + + /// Types with their associated subtypes + map> m_typesWithSubtypes; + + /// Paths of types, which have subtypes, and subtypes for the generator + vector> m_typesAndSubtypesPaths; +}; } // namespace ftypes