alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
DemangleTypeNames.hpp
Go to the documentation of this file.
1/* Copyright 2025 Andrea Bocci, Simeon Ehrig
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5/*
6 * C++20 compile-time demangled type name, based on
7 * https://www.reddit.com/r/cpp/comments/lfi6jt/finally_a_possibly_portable_way_to_convert_types/
8 * https://rodusek.com/posts/2021/03/09/getting-an-unmangled-type-name-at-compile-time/
9 */
10
11#pragma once
12
14
15#include <array>
16/** The following compilers does not use std::source_location therefore we do not include the header.
17 * Including the header source_location would lead into compiler issues under the following conditions.
18 * - nvcc is used with clang 15 as host compiler and MDSpan is used too.
19 * error: `include/c++/11/source_location(53): error: identifier "__builtin_source_location" is undefined`
20 */
21#if !(defined(__GNUC__) || defined(__clang__) || defined(__PGI) || defined(__NVCOMPILER) || defined(_MSC_VER))
22# if defined(__cpp_lib_source_location)
23# include <source_location>
24# endif
25#endif
26#include <string_view>
27#include <utility>
28
29namespace alpaka::core
30{
31
32 namespace detail
33 {
34
35 // Generate a function name with full type signature that includes the user-provided type name.
36 // Use the compiler-specific extensions for known compilers because nvc++ does not include the full type
37 // signature in std::source_location::current().function_name() .
38 template<typename T>
39 consteval std::string_view embedTypeName()
40 {
41#if defined(__GNUC__) || defined(__clang__) || defined(__PGI) || defined(__NVCOMPILER)
42 // gcc, clang, PGI, nvc++
44#elif defined(_MSC_VER)
45 // MSVC
46 return __FUNCSIG__;
47#elif defined(__cpp_lib_source_location)
48 // unknown compiler, use the c++20 standard function_name()
49 return std::source_location::current().function_name();
50#else
51 // std::source_location is not supported, fail
52# error \
53 "This compiler is not recognised and it does not support std::source_location. Please add explicit support to \"alpaka/core/DemangleTypeNames.hpp\"."
54#endif
55 }
56
57 // Use a fundamental type to detect the prefix and suffix, because MSVC includes the class, struct, or union
58 // keyword in the type signature.
60
61 constexpr std::string_view testPatternName("double");
62
63 // Embed the demangled type name into a function signature, then extract it and return it as a null-terminated
64 // array of bytes.
65 template<typename T>
66 consteval auto demangleAsArray()
67 {
68 // Embed a known type, and use it to extract the prefix and suffix generated by the compiler.
69 constexpr std::string_view embeddedPattern = embedTypeName<TestPatternType>();
70 constexpr size_t prefixSize = embeddedPattern.find(testPatternName);
71 constexpr size_t suffixSize = embeddedPattern.size() - prefixSize - testPatternName.size();
72
73 // Embed T, and use the known prefix and suffix length to determien the type name's position and size.
74 constexpr std::string_view embeddedType = embedTypeName<T>();
75 constexpr size_t start = prefixSize;
76 constexpr size_t end = embeddedType.size() - suffixSize;
77 static_assert(start < end);
78 constexpr size_t length = end - start;
79
80 // Copy the demangled type name into an array, and add a null terminaton character.
81 std::array<char, length + 1> storage{};
82 std::copy(embeddedType.data() + start, embeddedType.data() + end, storage.data());
83 storage[length] = '\0';
84#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
85# pragma clang diagnostic push
86# pragma clang diagnostic ignored "-Wnrvo"
87#endif
88 return storage;
89#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
90# pragma clang diagnostic pop
91#endif
92 }
93
94 // Store the demangled type name as a null-terminated array of bytes.
95 // Note: this could be a function-static constexpr variable in c++23.
96 template<typename T>
97 inline constexpr auto storage = demangleAsArray<T>();
98
99 // Return the demangled type name.
100 template<typename T>
101 consteval std::string_view demangle()
102 {
103 // Do not include the null terminaton character in the string_view.
104 return std::string_view{storage<T>.data(), storage<T>.size() - 1};
105 }
106
107 } // namespace detail
108
109 // constexpr template string_view that contains the demangled type name.
110 template<typename T>
111 inline constexpr std::string_view demangled = detail::demangle<T>();
112
113} // namespace alpaka::core
consteval std::string_view demangle()
consteval auto demangleAsArray()
consteval std::string_view embedTypeName()
constexpr std::string_view testPatternName("double")
constexpr std::string_view demangled
auto clipCast(V const &val) -> T
Definition ClipCast.hpp:16