From 667b2d27b7a9ce34c9ebe775312ac283a5144a38 Mon Sep 17 00:00:00 2001 From: Benjamin Nauck Date: Thu, 13 Feb 2025 20:28:43 +0100 Subject: [PATCH] Base: Minor cleanup * Add const * Add final * [[nodiscard]] * Fix parameter names * Add TypeId instead of unsigned int * Add "BadType" string constant Some some other tweaks --- src/Base/Type.cpp | 96 +++++++++++++++++++++++------------------------ src/Base/Type.h | 46 ++++++++++++----------- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/Base/Type.cpp b/src/Base/Type.cpp index 91605898ba..cf5d4d5bb1 100644 --- a/src/Base/Type.cpp +++ b/src/Base/Type.cpp @@ -33,7 +33,7 @@ using namespace Base; -static_assert(sizeof(Base::Type) == sizeof(unsigned int), +static_assert(sizeof(Base::Type) == sizeof(Type::TypeId), "Base::Type has been designed to be small to be passed around by value efficiently. " "The size of Base::Type has changed. Be careful when adding more data members."); @@ -45,22 +45,27 @@ static_assert( struct Base::TypeData { - TypeData(const char* theName, - const Type type = Type::BadType, - const Type theParent = Type::BadType, - Type::instantiationMethod method = nullptr) - : name(theName) - , parent(theParent) + TypeData(const char* name, + const Type type, + const Type parent, + const Type::instantiationMethod instMethod) + : name(name) + , parent(parent) , type(type) - , instMethod(method) + , instMethod(instMethod) {} - std::string name; - Type parent; - Type type; - Type::instantiationMethod instMethod; + const std::string name; + const Type parent; + const Type type; + const Type::instantiationMethod instMethod; }; +namespace +{ +constexpr const char* BadTypeName = "BadType"; +} + std::map Type::typemap; std::vector Type::typedata; std::set Type::loadModuleSet; @@ -79,26 +84,23 @@ bool Type::canInstantiate() const return method != nullptr; } -void* Type::createInstanceByName(const char* TypeName, bool bLoadModule) +void* Type::createInstanceByName(const char* typeName, bool loadModule) { // if not already, load the module - if (bLoadModule) { - importModule(TypeName); + if (loadModule) { + importModule(typeName); } // now the type should be in the type map - Type type = fromName(TypeName); - if (type == BadType) { - return nullptr; - } - + const Type type = fromName(typeName); + // let createInstance handle isBad check return type.createInstance(); } -void Type::importModule(const char* TypeName) +void Type::importModule(const char* typeName) { // cut out the module name - const std::string mod = getModuleName(TypeName); + const std::string mod = getModuleName(typeName); // ignore base modules if (mod == "App" || mod == "Gui" || mod == "Base") { @@ -106,22 +108,21 @@ void Type::importModule(const char* TypeName) } // remember already loaded modules - const auto pos = loadModuleSet.find(mod); - if (pos != loadModuleSet.end()) { + if (loadModuleSet.contains(mod)) { return; } // lets load the module Interpreter().loadModule(mod.c_str()); #ifdef FC_LOGLOADMODULE - Console().Log("Act: Module %s loaded through class %s \n", Mod.c_str(), TypeName); + Console().Log("Act: Module %s loaded through class %s \n", Mod.c_str(), typeName); #endif loadModuleSet.insert(mod); } -std::string Type::getModuleName(const char* ClassName) +const std::string Type::getModuleName(const char* className) { - std::string_view classNameView(ClassName); + std::string_view classNameView(className); auto pos = classNameView.find("::"); return pos != std::string_view::npos ? std::string(classNameView.substr(0, pos)) @@ -129,15 +130,16 @@ std::string Type::getModuleName(const char* ClassName) } -Type Type::createType(const Type parent, const char* name, instantiationMethod method) +const Type Type::createType(const Type parent, const char* name, instantiationMethod method) { + assert(name && name[0] != '\0' && "Type name must not be empty"); + Type newType; newType.index = static_cast(Type::typedata.size()); - TypeData* typeData = new TypeData(name, newType, parent, method); - Type::typedata.push_back(typeData); + Type::typedata.emplace_back(new TypeData(name, newType, parent, method)); // add to dictionary for fast lookup - Type::typemap[name] = newType.getKey(); + Type::typemap.emplace(name, newType.getKey()); return newType; } @@ -145,11 +147,9 @@ Type Type::createType(const Type parent, const char* name, instantiationMethod m void Type::init() { - assert(Type::typedata.empty()); - - - Type::typedata.push_back(new TypeData("BadType")); - Type::typemap["BadType"] = 0; + assert(Type::typedata.size() == 0 && "Type::init() should only be called once"); + typedata.emplace_back(new TypeData(BadTypeName, BadType, BadType, nullptr)); + typemap[BadTypeName] = 0; } void Type::destruct() @@ -162,19 +162,17 @@ void Type::destruct() loadModuleSet.clear(); } -Type Type::fromName(const char* name) +const Type Type::fromName(const char* name) { - std::map::const_iterator pos; - - pos = typemap.find(name); - if (pos != typemap.end()) { - return typedata[pos->second]->type; + const auto pos = typemap.find(name); + if (pos == typemap.end()) { + return Type::BadType; } - return Type::BadType; + return typedata[pos->second]->type; } -Type Type::fromKey(unsigned int key) +const Type Type::fromKey(TypeId key) { if (key < typedata.size()) { return typedata[key]->type; @@ -188,7 +186,7 @@ const char* Type::getName() const return typedata[index]->name.c_str(); } -Type Type::getParent() const +const Type Type::getParent() const { return typedata[index]->parent; } @@ -206,13 +204,13 @@ bool Type::isDerivedFrom(const Type type) const return false; } -int Type::getAllDerivedFrom(const Type type, std::vector& List) +int Type::getAllDerivedFrom(const Type type, std::vector& list) { int cnt = 0; for (auto it : typedata) { if (it->type.isDerivedFrom(type)) { - List.push_back(it->type); + list.push_back(it->type); cnt++; } } @@ -224,13 +222,13 @@ int Type::getNumTypes() return static_cast(typedata.size()); } -Type Type::getTypeIfDerivedFrom(const char* name, const Type parent, bool loadModule) +const Type Type::getTypeIfDerivedFrom(const char* name, const Type parent, bool loadModule) { if (loadModule) { importModule(name); } - if (Type type(fromName(name)); type.isDerivedFrom(parent)) { + if (const Type type(fromName(name)); type.isDerivedFrom(parent)) { return type; } diff --git a/src/Base/Type.h b/src/Base/Type.h index 1bcc25edc4..178912b3f8 100644 --- a/src/Base/Type.h +++ b/src/Base/Type.h @@ -77,9 +77,10 @@ struct TypeData; information: super classes must be registered before any of their derived classes are. */ -class BaseExport Type +class BaseExport Type final { public: + using TypeId = unsigned int; /// Construction Type(const Type& type) = default; Type(Type&& type) = default; @@ -88,33 +89,33 @@ public: ~Type() = default; /// creates a instance of this type - void* createInstance() const; + [[nodiscard]] void* createInstance() const; /// Checks whether this type can instantiate - bool canInstantiate() const; + [[nodiscard]] bool canInstantiate() const; /// creates a instance of the named type - static void* createInstanceByName(const char* TypeName, bool bLoadModule = false); + [[nodiscard]] static void* createInstanceByName(const char* typeName, bool loadModule = false); static void importModule(const char* TypeName); using instantiationMethod = void* (*)(); - static Type fromName(const char* name); - static Type fromKey(unsigned int key); - const char* getName() const; - Type getParent() const; - bool isDerivedFrom(const Type type) const; + [[nodiscard]] static const Type fromName(const char* name); + [[nodiscard]] static const Type fromKey(TypeId key); + [[nodiscard]] const char* getName() const; + [[nodiscard]] const Type getParent() const; + [[nodiscard]] bool isDerivedFrom(const Type type) const; - static int getAllDerivedFrom(const Type type, std::vector& List); + static int getAllDerivedFrom(const Type type, std::vector& list); /// Returns the given named type if is derived from parent type, otherwise return bad type - static Type + [[nodiscard]] static const Type getTypeIfDerivedFrom(const char* name, const Type parent, bool loadModule = false); - static int getNumTypes(); + [[nodiscard]] static int getNumTypes(); - static Type + [[nodiscard]] static const Type createType(const Type parent, const char* name, instantiationMethod method = nullptr); - unsigned int getKey() const; - bool isBad() const; + [[nodiscard]] TypeId getKey() const; + [[nodiscard]] bool isBad() const; Type& operator=(const Type& type) = default; Type& operator=(Type&& type) = default; @@ -130,19 +131,20 @@ public: static void init(); static void destruct(); - static std::string getModuleName(const char* ClassName); - + static const std::string getModuleName(const char* className); private: - unsigned int index {0}; + TypeId index {BadTypeIndex}; - static std::map typemap; - static std::vector typedata; + static std::map typemap; + static std::vector typedata; // use pointer to hide implementation details static std::set loadModuleSet; + + static constexpr TypeId BadTypeIndex = 0; }; -inline unsigned int Type::getKey() const +inline Type::TypeId Type::getKey() const { return this->index; } @@ -179,7 +181,7 @@ inline bool Type::operator>(const Type& type) const inline bool Type::isBad() const { - return (this->index == 0); + return this->index == BadTypeIndex; } } // namespace Base