Skip to main content

reflection-inlines.h File

C++ header file with inline implementations for the µTest++ reflection utilities. More...

Included Headers

#include <cstdint>

Namespaces Index

namespacemicro_os_plus

The primary namespace for the µOS++ framework. More...

namespacemicro_test_plus

Primary namespace for the µTest++ testing framework. More...

namespacereflection

Reflection utilities for the µTest++ testing framework. More...

Functions Index

template <class T>
constexpr std::string_viewtype_name (void)

Extract the type name from the __PRETTY_FUNCTION__ macro. More...

Description

C++ header file with inline implementations for the µTest++ reflection utilities.

This header provides the inline implementations for the reflection utilities used within the µTest++ framework. It includes the logic for capturing and reporting source location information, such as file names and line numbers, as well as utilities for extracting type names at compile time using compiler-specific macros.

The source_location implementation offers a lightweight, constexpr-compatible alternative to std::source_location, enabling enhanced diagnostics and reporting even in environments lacking C++20 support. The type_name utility leverages compiler intrinsics to obtain human-readable type names for improved test output and debugging.

All definitions reside within the micro_os_plus::micro_test_plus::reflection namespace, ensuring clear separation from user code and minimising the risk of naming conflicts.

The header files are organised within the include/micro-os-plus/micro-test-plus folder to maintain a structured and modular codebase.

This file is intended solely for internal use within the framework and should not be included directly by user code.

Functions

type_name()

template <class T>
std::string_view micro_os_plus::micro_test_plus::reflection::type_name (void)
nodiscard constexpr

Extract the type name from the __PRETTY_FUNCTION__ macro.

This function template parses the compiler-specific __PRETTY_FUNCTION__ macro to extract a concise type name for the template parameter T.

Rather than relying on fixed character offsets (which are fragile across compiler versions and namespace changes), the implementation searches for well-known marker characters in the function signature string:

  • Clang formats the signature as "... [T = <typename>]", so the type name lies between the last '[' (skipping "[T = ") and the last ']'.
  • GCC formats the signature as "... [with T = <typename>]", so the type name lies between the last '=' (skipping the trailing space) and the last ']'.

This approach is resilient to namespace renaming, namespace nesting changes, and compiler format updates.

Template Parameters
T

The type whose name is to be extracted.

Parameters

None.

Returns

A std::string_view containing the extracted type name.

Definition at line 146 of file reflection-inlines.h.

146 type_name (void) -> std::string_view
147 {
148 const std::string_view sv = __PRETTY_FUNCTION__;
149#if defined(__clang__)
150 // Clang: "... [T = <typename>]"
151 // rfind('[') locates the opening bracket of "[T = ...]".
152 const auto start = sv.rfind ('[') + 5; // skip "[T = "
153 const auto end = sv.rfind (']');
154#elif defined(__GNUC__)
155 // GCC: "... [with T = <typename>]" or, on some versions,
156 // "... [with T = <typename>; std::string_view = ...]"
157 // Search for "T = " explicitly to avoid landing on a later '='.
158 const auto t_eq = sv.find ("T = ");
159 const auto start = t_eq + 4; // skip "T = "
160 const auto semi = sv.find (';', start);
161 const auto end
162 = (semi != std::string_view::npos) ? semi : sv.rfind (']');
163#else
164// Note: MSVC uses __FUNCSIG__ instead of __PRETTY_FUNCTION__.
165// MSVC is not a supported target for this framework.
166#error "Unsupported compiler"
167#endif // defined(__clang__) || defined(__GNUC__)
168 return sv.substr (start, end - start);
169 }

Referenced by micro_os_plus::micro_test_plus::detail::expression_formatter::operator<<.

File Listing

The file content with the documentation metadata removed is:

1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can be
9 * obtained from https://opensource.org/licenses/mit.
10 *
11 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
12 * released under the terms of the Boost Version 1 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
47
48#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_REFLECTION_INLINES_H_
49#define MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_REFLECTION_INLINES_H_
50
51// ----------------------------------------------------------------------------
52
53#if defined(__cplusplus)
54
55// ----------------------------------------------------------------------------
56
57#include <cstdint>
58
59// ----------------------------------------------------------------------------
60
61#if defined(__GNUC__)
62#pragma GCC diagnostic push
63
64#pragma GCC diagnostic ignored "-Waggregate-return"
65#if defined(__clang__)
66#pragma clang diagnostic ignored "-Wc++98-compat"
67#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
68#endif // defined(__clang__)
69#endif // defined(__GNUC__)
70
71// ============================================================================
72
74{
75 // --------------------------------------------------------------------------
76
77 namespace reflection
78 {
79 // ------------------------------------------------------------------------
80
81#if !defined(__cpp_lib_source_location)
82
91 constexpr source_location
92 source_location::current (const char* file, unsigned int line) noexcept
93 {
95 sl.file_ = file;
96 sl.line_ = line;
97 return sl;
98 }
99
105 constexpr auto
106 source_location::file_name (void) const noexcept
107 {
108 return file_;
109 }
110
116 constexpr auto
117 source_location::line (void) const noexcept
118 {
119 return line_;
120 }
121
122#endif // !defined(__cpp_lib_source_location)
123
144 template <class T>
145 constexpr auto
146 type_name (void) -> std::string_view
147 {
148 const std::string_view sv = __PRETTY_FUNCTION__;
149#if defined(__clang__)
150 // Clang: "... [T = <typename>]"
151 // rfind('[') locates the opening bracket of "[T = ...]".
152 const auto start = sv.rfind ('[') + 5; // skip "[T = "
153 const auto end = sv.rfind (']');
154#elif defined(__GNUC__)
155 // GCC: "... [with T = <typename>]" or, on some versions,
156 // "... [with T = <typename>; std::string_view = ...]"
157 // Search for "T = " explicitly to avoid landing on a later '='.
158 const auto t_eq = sv.find ("T = ");
159 const auto start = t_eq + 4; // skip "T = "
160 const auto semi = sv.find (';', start);
161 const auto end
162 = (semi != std::string_view::npos) ? semi : sv.rfind (']');
163#else
164// Note: MSVC uses __FUNCSIG__ instead of __PRETTY_FUNCTION__.
165// MSVC is not a supported target for this framework.
166#error "Unsupported compiler"
167#endif // defined(__clang__) || defined(__GNUC__)
168 return sv.substr (start, end - start);
169 }
170
171 // ------------------------------------------------------------------------
172 } // namespace reflection
173
174 // --------------------------------------------------------------------------
175} // namespace micro_os_plus::micro_test_plus
176
177#if defined(__GNUC__)
178#pragma GCC diagnostic pop
179#endif // defined(__GNUC__)
180
181// ----------------------------------------------------------------------------
182
183#endif // defined(__cplusplus)
184
185// ----------------------------------------------------------------------------
186
187#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_REFLECTION_INLINES_H_
188
189// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.2 by Doxygen 1.17.0.