Skip to content

Commit e0e9e73

Browse files
committed
Avoid using RTTI for list tests when possible
With Clang, GCC and MSVC, we can generate the typename using compiler macros and some string manipulation. Where this is possible, we will use this instead of RTTI. Where it is not, we will fall back to RTTI and/or index-based default typename string generation. Special thanks to Corentin Schreiber ([email protected]) for the inspiration here.
1 parent 4ea5237 commit e0e9e73

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

src/catch2/internal/catch_template_test_registry.hpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <catch2/internal/catch_compiler_capabilities.hpp>
1313
#include <catch2/internal/catch_preprocessor.hpp>
1414
#include <catch2/internal/catch_meta.hpp>
15+
#include <catch2/internal/catch_to_string.hpp>
1516
#include <catch2/internal/catch_unique_name.hpp>
1617

1718
#if defined(CATCH_CONFIG_USE_RTTI) || (defined(CATCH_INTERNAL_RTTI_SUPPORTED) && !defined(CATCH_INTERNAL_USE_NO_RTTI))
@@ -353,6 +354,33 @@ namespace Catch {
353354
template <typename T>
354355
struct IndexedTestTypeName {
355356
std::string operator()(size_t index) const {
357+
#if defined(CATCH_CONFIG_CPP17_STRING_VIEW) || !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW)
358+
#if defined(__clang__)
359+
constexpr auto prefix = std::string_view{"[T = "};
360+
constexpr auto suffix = "]";
361+
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
362+
#elif defined(__GNUC__)
363+
constexpr auto prefix = std::string_view{"with T = "};
364+
constexpr auto suffix = "; ";
365+
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
366+
#elif defined(_MSC_VER)
367+
constexpr auto prefix = std::string_view{"get_type_name<"};
368+
constexpr auto suffix = ">(size_t)";
369+
constexpr auto function = std::string_view{__FUNCSIG__};
370+
#else
371+
constexpr std::string_view prefix;
372+
constexpr std::string_view suffix;
373+
constexpr std::string_view function;
374+
if (false) // make sure we don't execute this substr block immediately below
375+
#endif
376+
{
377+
const auto start = function.find(prefix) + prefix.size();
378+
const auto end = function.find(suffix, start);
379+
const auto size = end - start;
380+
return std::string{function.substr(start, size)};
381+
}
382+
#endif
383+
356384
#if defined(CATCH_INTERNAL_USE_RTTI)
357385
const char* name = typeid(T).name();
358386
int status = 0;
@@ -361,9 +389,9 @@ namespace Catch {
361389
return demangled.get();
362390
}
363391
#endif
364-
return std::to_string(index);
392+
return Catch::to_string<size_t>(index);
365393
}
366394
};
367-
}
395+
} // namespace Catch
368396

369397
#endif // CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED

0 commit comments

Comments
 (0)