From ad59054918ab485dc79e113bea38aa9a852ee328 Mon Sep 17 00:00:00 2001 From: Benjamin Nauck Date: Fri, 7 Mar 2025 15:53:04 +0100 Subject: [PATCH] Refactor static type checks --- src/App/PropertyContainer.h | 40 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/App/PropertyContainer.h b/src/App/PropertyContainer.h index c20cc2a9cf..835803219d 100644 --- a/src/App/PropertyContainer.h +++ b/src/App/PropertyContainer.h @@ -319,19 +319,12 @@ private: \ #define PROPERTY_HEADER_WITH_OVERRIDE(_class_) \ TYPESYSTEM_HEADER_WITH_OVERRIDE(); \ public: \ - static constexpr const char* getClassName() {\ - /* - TODO: When c++20 is available \ - - Use consteval to ensure the function is evaluated at compile time \ - - Move bulk of the function to a template `validate()` \ - - Use `starts_with` when checking namespace in path \ - */ \ - \ + static consteval const char* getClassName() {\ static_assert(sizeof(_class_) > 0, "Class is not complete"); \ \ constexpr const char* sClass = #_class_; \ constexpr std::string_view vClass {sClass}; \ - static_assert(vClass[0] != '\0', "Class name must not be empty"); \ + static_assert(!vClass.empty(), "Class name must not be empty"); \ static_assert(std::is_base_of::value, \ "Class must be derived from App::PropertyContainer"); \ \ @@ -341,22 +334,23 @@ public: \ constexpr auto pos = vClass.find("::"); \ static_assert(pos != std::string_view::npos, \ "Class name must be fully qualified for document object derived classes"); \ - static_assert(pos != 0, "Namespace must not be empty"); \ - \ constexpr auto vNamespace = vClass.substr(0, pos); \ + static_assert(!vNamespace.empty(), "Namespace must not be empty"); \ + \ constexpr std::string_view filePath = __FILE__; \ - constexpr auto posAfterSrcMod = filePath.find("/src/Mod/"); \ - if constexpr (constexpr bool hasSrcModInPath = posAfterSrcMod != std::string_view::npos) { \ - constexpr auto pathAfterSrcMod = filePath.substr(posAfterSrcMod + 9); \ - /* some workarounds are needed, if CI is ok in the future, remove these: \ - - isSubClassOfDocObj shouldn't be needed, but it is for some compilers \ - - allowing `Path` until it's been properly renamed */ \ - constexpr bool workarounds = !isSubClassOfDocObj || vNamespace == "Path"; \ - /* TODO: use `starts_with` instead of `find` when c++20 is available */ \ - constexpr bool isPathOk = pathAfterSrcMod.find(vNamespace) != std::string_view::npos; \ - static_assert(workarounds || isPathOk, \ - "Classes in `src/Mod` needs to be in a directory with the same name as" \ - " the namespace in order to load correctly"); \ + constexpr std::string_view modPath = "/src/Mod/"; \ + constexpr auto posAfterSrcMod = filePath.find(modPath); \ + constexpr bool hasSrcModInPath = posAfterSrcMod != std::string_view::npos; \ + if constexpr (hasSrcModInPath) { \ + constexpr auto pathAfterSrcMod = filePath.substr(posAfterSrcMod + modPath.size()); \ + constexpr bool isPathOk = pathAfterSrcMod.starts_with(vNamespace); \ + static_assert( \ + /* some compilers evaluate static_asserts inside ifs before checking it's a valid codepath */ \ + !isSubClassOfDocObj || !hasSrcModInPath || \ + /* allow `Path` until it's been properly renamed to CAM */ \ + vNamespace == "Path" || isPathOk, \ + "Classes in `src/Mod` needs to be in a directory with the same name as" \ + " the namespace in order to load correctly"); \ } \ } \ return sClass; \