Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
type_name_string.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_INFO_TYPE_NAME_STRING_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_INFO_TYPE_NAME_STRING_HPP_
7
8// IWYU pragma: private, include "arene/base/type_info.hpp"
9// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
10
11// parasoft-begin-suppress AUTOSAR-A7_1_5-a-2 "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
12
13// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
14#include "arene/base/algorithm/copy.hpp"
15#include "arene/base/array/array.hpp"
16#include "arene/base/constraints/constraints.hpp"
17#include "arene/base/contracts/contract.hpp"
18#include "arene/base/iterator/next.hpp"
19#include "arene/base/stdlib_choice/cstddef.hpp"
20#include "arene/base/stdlib_choice/enable_if.hpp"
21#include "arene/base/stdlib_choice/ignore.hpp"
22#include "arene/base/stdlib_choice/is_void.hpp"
23#include "arene/base/string_algorithms.hpp"
24#include "arene/base/strings/inline_string.hpp"
25#include "arene/base/strings/string_view.hpp"
26// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
27
28namespace arene {
29namespace base {
30namespace type_name_string_detail {
31
32// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
33// parasoft-begin-suppress AUTOSAR-A3_9_1-b "Use of char for compatibility with std::string_view"
34/// @brief Get a hint of the required length of a string which includes the name of the type @c T, but with other
35/// characters before and after, and padding afterwards. This won't be exact, because this is a different function to
36/// get_big_raw_type_name
37/// @tparam T The type to get the name of
38/// @return std::size_t holding the length hint
39template <typename T>
40constexpr auto get_big_raw_type_name_length_hint() noexcept -> std::size_t {
41 return arene::base::string_length(static_cast<char const*>(__PRETTY_FUNCTION__));
42}
43// parasoft-end-suppress AUTOSAR-A3_9_1-b
44// parasoft-end-suppress AUTOSAR-M3_3_2-a
45
46/// @brief The hint length for @c void to avoid duplicate function evaluation.
47/// Uses a dummy template parameter so it is a template for initialization in header file without ODR violation
48template <std::nullptr_t = nullptr>
49extern constexpr std::size_t void_length_hint = get_big_raw_type_name_length_hint<void>();
50
51/// @brief The length of the buffer to use for @c big_raw_type_name<T>
52/// The primary template is only used for @c void the specialization below determines the exact size for other types
53/// @tparam T The type to get the length of the raw name for
54template <typename T, typename = constraints<>>
55extern constexpr std::size_t raw_type_name_buffer_size = 200; // default value, used for void
56
57// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
58// parasoft-begin-suppress AUTOSAR-A3_9_1 "Use of char for compatibility with std::string_view"
59/// @brief Get a string which includes the name of the type @c T, but with other
60/// characters before and after, and padding afterwards.
61/// @tparam T The type to get the name of
62/// @return array<char> containing a nul-terminated string including the
63/// name
64template <typename T>
65constexpr auto get_big_raw_type_name() noexcept -> array<char, raw_type_name_buffer_size<T>> {
66 array<char, raw_type_name_buffer_size<T>> res{};
67 char const* name_str{static_cast<char const*>(__PRETTY_FUNCTION__)};
68 auto const length = string_length(name_str);
69 std::ignore = copy(name_str, arene::base::next(name_str, static_cast<std::ptrdiff_t>(length)), res.begin());
70 res[length] = 0;
71 return res;
72}
73// parasoft-end-suppress AUTOSAR-A3_9_1
74// parasoft-end-suppress AUTOSAR-M3_3_2-a
75
76/// @brief A variable holding a string which includes the name of the type @c T, but
77/// with other characters before and after, and padding afterwards.
78/// @tparam T The type to get the name of
79template <typename T>
80extern constexpr auto big_raw_type_name = get_big_raw_type_name<T>();
81
82/// @brief The length of the string stored in @c big_raw_type_name<T>
83/// @tparam T The type to get the length of the raw name for
84template <typename T>
85extern constexpr std::size_t raw_type_name_length = arene::base::string_length(big_raw_type_name<T>.data());
86
87/// @brief The length of the buffer to use for @c big_raw_type_name<T>.
88/// This specialization handles the non-void case, and determines the exact required length of the buffer to hold the
89/// string plus terminating @c NUL, using the length hint, in order to avoid excessive storage for short names, and
90/// insufficient storage for long ones
91/// @tparam T The type to get the length of the raw name for
92template <typename T>
93extern constexpr std::size_t raw_type_name_buffer_size<T, constraints<std::enable_if_t<!std::is_void<T>::value>>> =
94 get_big_raw_type_name_length_hint<T>() - void_length_hint<> + raw_type_name_length<void> + 1;
95
96static_assert(
97 raw_type_name_buffer_size<bool> == raw_type_name_length<bool> + 1,
98 "The buffer for a non-void type must be just big enough for the name"
99);
100
101// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
102/// @brief Get a string view that contains the name of the type @c T, as part of a longer string
103/// @tparam T The type to get the string for
104/// @return a string_view containing the name of the type
105template <typename T>
106constexpr auto get_raw_type_name_string_view() noexcept -> string_view {
107 return {big_raw_type_name<T>.data(), raw_type_name_length<T>};
108}
109// parasoft-end-suppress AUTOSAR-M3_3_2-a
110
111/// @brief A struct holding the distance from the start of the helper string to the type name, and the number of
112/// trailing characters after the type name
113struct name_offsets {
114 /// @brief The number of characters before the type name
115 std::size_t characters_before;
116 /// @brief The number of characters after the type name
117 std::size_t characters_after;
118};
119
120/// @brief Get the characters before and after the type name in the helper string. Instantiates the helper string
121/// template with a type with a known name (@c void), and searches for that name in the returned string.
122/// @return A @c NameOffsets struct holding the number of characters before and after the type name
123inline constexpr auto get_name_offsets() noexcept -> name_offsets {
124 constexpr string_view void_str{"void"};
125 constexpr string_view void_name{get_raw_type_name_string_view<void>()};
126 constexpr std::size_t pos{void_name.find(void_str)};
127
128 // parasoft-begin-suppress CERT_C-PRE31-c "False positive: static_assert is a compile-time assert and can have no
129 // side-effects"
130 static_assert(pos < void_name.size(), "'void' not found in function name");
131 // parasoft-end-suppress CERT_C-PRE31-c
132 return {pos, void_name.size() - (pos + void_str.size())};
133}
134
135/// @brief The offsets for the loaction of the type name within the raw string
136/// Uses a dummy template parameter so it is a template for initialization in header file without ODR violation
137template <std::nullptr_t = nullptr>
138extern constexpr name_offsets offsets = get_name_offsets();
139
140// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
141// parasoft-begin-suppress AUTOSAR-A8_4_2-a "ARENE_INVARIANT terminates, so does not need a return for its execution
142// path"
143// parasoft-begin-suppress CERT_CPP-MSC52-a "ARENE_INVARIANT terminates, so does not need a return for its execution
144// path"
145// parasoft-begin-suppress CERT_C-MSC37-a "ARENE_INVARIANT terminates, so does not need a return for its execution path"
146
147/// @brief Get the length of a type's name
148/// @tparam T The type to get the name length of
149/// @return std::size_t holding the length
150template <typename T>
151constexpr auto get_type_name_string_length() noexcept -> std::size_t {
152 constexpr string_view full_name{get_raw_type_name_string_view<T>()};
153 ARENE_INVARIANT(offsets<>.characters_before < full_name.size());
154 ARENE_INVARIANT(offsets<>.characters_after < (full_name.size() - offsets<>.characters_before));
155 return full_name.size() - (offsets<>.characters_before + offsets<>.characters_after);
156}
157// parasoft-end-suppress CERT_C-MSC37-a-2
158// parasoft-end-suppress CERT_CPP-MSC52-a-2
159// parasoft-end-suppress AUTOSAR-A8_4_2-a-2
160// parasoft-end-suppress AUTOSAR-M3_3_2-a
161
162/// @brief The length of a type's name
163/// @tparam T The type to get the name length of
164template <typename T>
165extern constexpr std::size_t type_name_string_length = get_type_name_string_length<T>();
166
167// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: function is implicitly inline"
168/// @brief Get the name of a type as an @c inline_string
169/// @tparam T The type to get the name of
170/// @return inline_string holding the name
171template <typename T>
172constexpr auto get_type_name_string() noexcept -> inline_string<type_name_string_length<T>> {
173 constexpr string_view full_name{get_raw_type_name_string_view<T>()};
174 ARENE_INVARIANT(offsets<>.characters_before < full_name.size());
175 ARENE_INVARIANT(type_name_string_length<T> < (full_name.size() - offsets<>.characters_before));
176 return inline_string<type_name_string_length<T>>{
177 full_name.substr(offsets<>.characters_before, type_name_string_length<T>)
178 };
179}
180// parasoft-end-suppress AUTOSAR-M3_3_2-a
181
182} // namespace type_name_string_detail
183
184/// @brief The name of a type as an @c inline_string
185/// @tparam T The type to get the name of
186template <typename T>
188} // namespace base
189} // namespace arene
190#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_INFO_TYPE_NAME_STRING_HPP_
Definition array_exceptions_disabled.cpp:11
constexpr auto type_name_v
The name of a type as an inline_string.
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10