@@ -319,19 +319,12 @@ private: \
319319#define PROPERTY_HEADER_WITH_OVERRIDE (_class_ ) \
320320 TYPESYSTEM_HEADER_WITH_OVERRIDE (); \
321321public: \
322- static constexpr const char * getClassName () {\
323- /*
324- TODO: When c++20 is available \
325- - Use consteval to ensure the function is evaluated at compile time \
326- - Move bulk of the function to a template `validate<T, _class_, #_class>()` \
327- - Use `starts_with` when checking namespace in path \
328- */ \
329- \
322+ static consteval const char * getClassName () {\
330323 static_assert (sizeof (_class_) > 0 , " Class is not complete" ); \
331324 \
332325 constexpr const char * sClass = #_class_; \
333326 constexpr std::string_view vClass {sClass }; \
334- static_assert (vClass[ 0 ] != ' \0 ' , " Class name must not be empty" ); \
327+ static_assert (!vClass. empty () , " Class name must not be empty" ); \
335328 static_assert (std::is_base_of<App::PropertyContainer, _class_>::value, \
336329 " Class must be derived from App::PropertyContainer" ); \
337330 \
@@ -341,22 +334,23 @@ public: \
341334 constexpr auto pos = vClass.find (" ::" ); \
342335 static_assert (pos != std::string_view::npos, \
343336 " Class name must be fully qualified for document object derived classes" ); \
344- static_assert (pos != 0 , " Namespace must not be empty" ); \
345- \
346337 constexpr auto vNamespace = vClass.substr (0 , pos); \
338+ static_assert (!vNamespace.empty (), " Namespace must not be empty" ); \
339+ \
347340 constexpr std::string_view filePath = __FILE__; \
348- constexpr auto posAfterSrcMod = filePath.find (" /src/Mod/" ); \
349- if constexpr (constexpr bool hasSrcModInPath = posAfterSrcMod != std::string_view::npos) { \
350- constexpr auto pathAfterSrcMod = filePath.substr (posAfterSrcMod + 9 ); \
351- /* some workarounds are needed, if CI is ok in the future, remove these: \
352- - isSubClassOfDocObj shouldn't be needed, but it is for some compilers \
353- - allowing `Path` until it's been properly renamed */ \
354- constexpr bool workarounds = !isSubClassOfDocObj || vNamespace == " Path" ; \
355- /* TODO: use `starts_with` instead of `find` when c++20 is available */ \
356- constexpr bool isPathOk = pathAfterSrcMod.find (vNamespace) != std::string_view::npos; \
357- static_assert (workarounds || isPathOk, \
358- " Classes in `src/Mod` needs to be in a directory with the same name as" \
359- " the namespace in order to load correctly" ); \
341+ constexpr std::string_view modPath = " /src/Mod/" ; \
342+ constexpr auto posAfterSrcMod = filePath.find (modPath); \
343+ constexpr bool hasSrcModInPath = posAfterSrcMod != std::string_view::npos; \
344+ if constexpr (hasSrcModInPath) { \
345+ constexpr auto pathAfterSrcMod = filePath.substr (posAfterSrcMod + modPath.size ()); \
346+ constexpr bool isPathOk = pathAfterSrcMod.starts_with (vNamespace); \
347+ static_assert ( \
348+ /* some compilers evaluate static_asserts inside ifs before checking it's a valid codepath */ \
349+ !isSubClassOfDocObj || !hasSrcModInPath || \
350+ /* allow `Path` until it's been properly renamed to CAM */ \
351+ vNamespace == " Path" || isPathOk, \
352+ " Classes in `src/Mod` needs to be in a directory with the same name as" \
353+ " the namespace in order to load correctly" ); \
360354 } \
361355 } \
362356 return sClass ; \
0 commit comments