diff --git a/kratos/includes/define_registry.h b/kratos/includes/define_registry.h index 01a1eded6315..d37d57294ba3 100644 --- a/kratos/includes/define_registry.h +++ b/kratos/includes/define_registry.h @@ -53,14 +53,14 @@ return Registry::HasItem(key_name); \ }(); -#define KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE(NAME, X, Y, ...) \ +#define KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE(NAME, X, Y) \ static inline bool KRATOS_REGISTRY_NAME(_is_registered_, __LINE__) = []() -> bool { \ - using TFunctionType = std::function()>; \ - std::string key_name = NAME + std::string(".") + std::string(#Y) + "<" + Kratos::Registry::RegistryTemplateToString(__VA_ARGS__) + ">"; \ + using TFunctionType = std::function()>; \ + std::string key_name = NAME + std::string(".") + Registry::GetDemangledName(typeid(static_cast(nullptr)).name()); \ if (!Registry::HasItem(key_name)) \ { \ auto &r_item = Registry::AddItem(key_name); \ - TFunctionType dispatcher = [](){return std::make_shared>();}; \ + TFunctionType dispatcher = [](){return std::make_shared();}; \ r_item.AddItem("Prototype", std::move(dispatcher)); \ } else { \ } \ diff --git a/kratos/includes/registry.h b/kratos/includes/registry.h index b9397022f967..97537675a619 100644 --- a/kratos/includes/registry.h +++ b/kratos/includes/registry.h @@ -122,17 +122,16 @@ class KRATOS_API(KRATOS_CORE) Registry final } /** - * @brief Converts template arguments to a string representation - * @tparam Types Variadic template types - * @param args Arguments to convert to string - * @return A comma-separated string representation of the arguments + * @brief Gets the registry name from a given demangled type name (no type suffixes and no namespaces) + * @return Registry name of a given type */ - template - static std::string RegistryTemplateToString(Types&&... args) { - std::string f_name = (... += ("," + std::to_string(args))); - f_name.erase(0,1); - return f_name; - } + static std::string GetRegistryName(std::string demangled_name); + + /** + * @brief Gets the demangled name from a given type name + * @return Demanged name of a given type + */ + static std::string GetDemangledName(const char* name); ///@} ///@name Iterators diff --git a/kratos/processes/apply_ray_casting_interface_recognition_process.h b/kratos/processes/apply_ray_casting_interface_recognition_process.h index 76f4054649e8..6b91c5fe7e1a 100644 --- a/kratos/processes/apply_ray_casting_interface_recognition_process.h +++ b/kratos/processes/apply_ray_casting_interface_recognition_process.h @@ -44,8 +44,10 @@ class KRATOS_API(KRATOS_CORE) ApplyRayCastingInterfaceRecognitionProcess : publi /// Pointer definition of ApplyRayCastingInterfaceRecognitionProcess KRATOS_CLASS_POINTER_DEFINITION(ApplyRayCastingInterfaceRecognitionProcess); - KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.KratosMultiphysics", Process, ApplyRayCastingInterfaceRecognitionProcess, TDim) - KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.All", Process, ApplyRayCastingInterfaceRecognitionProcess, TDim) + using RegistryBaseType = Process; + using RegistryClassType = ApplyRayCastingInterfaceRecognitionProcess; + KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.KratosMultiphysics", RegistryBaseType, RegistryClassType) + KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.All", RegistryBaseType, RegistryClassType) ///@} ///@name Life Cycle diff --git a/kratos/processes/apply_ray_casting_process.h b/kratos/processes/apply_ray_casting_process.h index 8403e1ef1d58..7c9d24a1225b 100644 --- a/kratos/processes/apply_ray_casting_process.h +++ b/kratos/processes/apply_ray_casting_process.h @@ -50,8 +50,10 @@ class KRATOS_API(KRATOS_CORE) ApplyRayCastingProcess : public Process /// Pointer definition of ApplyRayCastingProcess KRATOS_CLASS_POINTER_DEFINITION(ApplyRayCastingProcess); - KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.KratosMultiphysics", Process, ApplyRayCastingProcess, TDim) - KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.All", Process, ApplyRayCastingProcess, TDim) + using RegistryBaseType = Process; + using RegistryClassType = ApplyRayCastingProcess; + KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.KratosMultiphysics", Process, RegistryClassType) + KRATOS_REGISTRY_ADD_TEMPLATE_PROTOTYPE("Processes.All", Process, RegistryClassType) //TODO: These using statements have been included to make the old functions able to compile. It is still pending to update them. using ConfigurationType = Internals::DistanceSpatialContainersConfigure; diff --git a/kratos/sources/registry.cpp b/kratos/sources/registry.cpp index fedfe74dcdf0..479f91679301 100644 --- a/kratos/sources/registry.cpp +++ b/kratos/sources/registry.cpp @@ -13,12 +13,19 @@ // System includes #include +#include +#include // External includes // Project includes #include "includes/registry.h" +// Demangle OS includes +#if defined(__GNUG__) || defined(__clang__) + #include +#endif + namespace Kratos { @@ -137,6 +144,39 @@ namespace return GetItem(rItemFullName).HasItems(); } + std::string Registry::GetRegistryName(std::string d_name) { + // Remove namespace + static const std::regex ns_re(R"(\b[\w_]+::)"); + d_name = std::regex_replace(d_name, ns_re, ""); + + // Remove literal suffix + static const std::regex suffix_re(R"(\b(\d+)(ull|ul|ll|l|u|f|L)\b)"); + d_name = std::regex_replace(d_name, suffix_re, "$1"); + + // Strip all spaces + static const std::regex space_re(R"(\s+)"); + d_name = std::regex_replace(d_name, space_re, ""); + + // Strip the trailing * from the usage of pointer types (Some demanglers leave that, some other do not) + d_name = std::regex_replace(d_name, std::regex("(>?)\\*$"), "$1"); + + return d_name; + } + +#if defined(__GNUG__) || defined(__clang__) + std::string Registry::GetDemangledName(const char* name) { + int status = 0; + std::unique_ptr res { + abi::__cxa_demangle(name, nullptr, nullptr, &status), + std::free + }; + return (status == 0) ? Registry::GetRegistryName(res.get()) : name; + } +#else + std::string Registry::GetDemangledName(const char* name) { return Registry::GetRegistryName(name); } +#endif + + std::string Registry::Info() const { return "Registry"; diff --git a/kratos/tests/cpp_tests/sources/test_registry.cpp b/kratos/tests/cpp_tests/sources/test_registry.cpp index f6c503cf3472..2192c0e085cd 100644 --- a/kratos/tests/cpp_tests/sources/test_registry.cpp +++ b/kratos/tests/cpp_tests/sources/test_registry.cpp @@ -314,4 +314,68 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryIsSameType, KratosCoreFastSuite) { KRATOS_EXPECT_FALSE(Registry::GetItem("variables.all.VELOCITY").IsSameType(test_double)); } +namespace RegistryTestNamespace { + class _Boo {}; // Normal class name + class _Boo2 {}; // Class name with number + class _Boo2L {}; // Class name with number and suffix + + template class _FooCT {}; + template class _FooC {}; + template class _FooT {}; + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerClassValue, KratosCoreFastSuite) { + + _FooCT<_Boo, 2> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooCT<_Boo,2>"); + } + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerClassValueWithNumberClassName, KratosCoreFastSuite) { + + _FooCT<_Boo2, 2> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooCT<_Boo2,2>"); + } + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerClassValueWithNumberAndSuffixClassName, KratosCoreFastSuite) { + + _FooCT<_Boo2L, 2> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooCT<_Boo2L,2>"); + } + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerClassOnly, KratosCoreFastSuite) { + + _FooC<_Boo> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooC<_Boo>"); + } + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerValueOnly, KratosCoreFastSuite) { + + _FooT<2> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooT<2>"); + } + + KRATOS_TEST_CASE_IN_SUITE(RegistryNameDemanglerTemplateHell, KratosCoreFastSuite) { + + _FooCT<_FooCT<_FooC<_Boo2>,3ull>,2L> foo_instance; + + auto demangled_name = Registry::GetDemangledName(typeid(foo_instance).name()); + + KRATOS_EXPECT_EQ(demangled_name, "_FooCT<_FooCT<_FooC<_Boo2>,3>,2>"); + } +} + } // namespace Kratos::Testing.