Skip to main content

reflection.h File

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

Included Headers​

#include <string_view> #include <version> #include "inlines/reflection-inlines.h"

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...

Classes Index​

classsource_location

Local implementation of source location information for diagnostics. More...

Functions Index​

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

Extracts the type name from the __PRETTY_FUNCTION__ identifier. More...

Description​

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

This header provides the declarations for the reflection utilities used within the µTest++ framework. It defines interfaces for obtaining source location information and extracting type names at compile time, for the reports of the checks.

The reflection utilities include a local implementation of source_location for standard libraries that do not yet provide std::source_location, and a function to extract concise type names using the compiler-specific __PRETTY_FUNCTION__ identifier. These facilities enable precise identification of code locations and types in test reports.

All definitions reside within the micro_os_plus::micro_test_plus::reflection namespace.

This file is included by micro-os-plus/micro-test-plus.h, which is the header that the applications include.

Functions​

type_name()​

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

Extracts the type name from the __PRETTY_FUNCTION__ identifier.

This function template parses the compiler-specific __PRETTY_FUNCTION__ identifier 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 the marker that introduces the template argument in the function signature string:

  • Clang formats the signature as "... [T = <typename>]", so the type name lies between the first "[T = " and the last ']'. The marker is searched for as a whole, since the type name may itself contain brackets (e.g. int[3]).
  • GCC formats the signature as "... [with T = <typename>]" or, on some versions, "... [with T = <typename>; ...]", so the type name starts after the first "[with T = " and ends at the following ';' or, if there is none, at the last ']'.

If the marker is not found, or the compiler is not supported (e.g. MSVC, which uses __FUNCSIG__ instead of __PRETTY_FUNCTION__), the function returns "unknown" rather than failing to compile, since the name is used only to improve the test output.

The expected layouts are verified at compile time by the static_assert checks that follow the definition.

The name is spelled as the compiler prints it, and is used to identify the expected exception type in the throws<E> failure messages. Only clang and GCC are supported; with other compilers the function returns "unknown".

Template Parameters
T

The type whose name is to be extracted.

Parameters

None.

Returns

A std::string_view containing the extracted type name, or "unknown" if it cannot be determined.

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

149 type_name (void) -> std::string_view
150 {
151#if defined(__clang__)
152 // Clang: "... [T = <typename>]"
153 const std::string_view sv = __PRETTY_FUNCTION__;
154 constexpr std::string_view marker{ "[T = " };
155 const auto pos = sv.find (marker);
156 const auto end = sv.rfind (']');
157#elif defined(__GNUC__)
158 // GCC: "... [with T = <typename>]" or, on some versions,
159 // "... [with T = <typename>; std::string_view = ...]"
160 const std::string_view sv = __PRETTY_FUNCTION__;
161 constexpr std::string_view marker{ "[with T = " };
162 const auto pos = sv.find (marker);
163 const auto semi = sv.find (';', pos);
164 const auto end
165 = (semi != std::string_view::npos) ? semi : sv.rfind (']');
166#else
167 // Unsupported compiler; no portable signature string is available.
168 const std::string_view sv{};
169 constexpr std::string_view marker{};
170 const auto pos = std::string_view::npos;
171 const auto end = std::string_view::npos;
172#endif // defined(__clang__) || defined(__GNUC__)
173 if (pos == std::string_view::npos || end == std::string_view::npos
174 || end < pos + marker.size ())
175 {
176 return "unknown";
177 }
178 const auto start = pos + marker.size ();
179 return sv.substr (start, end - start);
180 }

Reference micro_os_plus::micro_test_plus::reflection::type_name.

Referenced by micro_os_plus::micro_test_plus::detail::expression_formatter::operator<< and micro_os_plus::micro_test_plus::reflection::type_name.

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.0 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
41
42#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_REFLECTION_H_
43#define MICRO_OS_PLUS_MICRO_TEST_PLUS_REFLECTION_H_
44
45// ----------------------------------------------------------------------------
46
47#if defined(__cplusplus)
48
49// ----------------------------------------------------------------------------
50
51#if __has_include("micro-os-plus/project-config.h")
52#include "micro-os-plus/project-config.h"
53#endif // __has_include("micro-os-plus/project-config.h")
54
55#if __has_include("micro-os-plus/micro-test-plus-defines.h")
56#include "micro-os-plus/micro-test-plus-defines.h"
57#endif // __has_include("micro-os-plus/micro-test-plus-defines.h")
58
59#include <string_view>
60// Defines `__cpp_lib_source_location` regardless of the headers included
61// before this one, so that all translation units choose the same
62// `source_location` type.
63#include <version>
64
65#if defined(__cpp_lib_source_location)
66#include <source_location>
67#endif // defined(__cpp_lib_source_location)
68
69// ----------------------------------------------------------------------------
70
71#if defined(__GNUC__)
72#pragma GCC diagnostic push
73
74#pragma GCC diagnostic ignored "-Wpadded"
75#pragma GCC diagnostic ignored "-Waggregate-return"
76#if defined(__clang__)
77#pragma clang diagnostic ignored "-Wc++98-compat"
78#endif // defined(__clang__)
79#endif // defined(__GNUC__)
80
81// ============================================================================
82
84{
85 // --------------------------------------------------------------------------
86
101 namespace reflection
102 {
103 // ------------------------------------------------------------------------
104
105#if defined(__cpp_lib_source_location)
106
118 using source_location = std::source_location;
119
120#else
121
143 {
144 public:
152 [[nodiscard]] static constexpr source_location
153 current (
154#if (__has_builtin(__builtin_FILE) and __has_builtin(__builtin_LINE))
155 const char* file = __builtin_FILE (),
156 unsigned int line = __builtin_LINE ()
157#else
158 const char* file = "unknown", unsigned int line = {}
159#endif // (__has_builtin(__builtin_FILE) and __has_builtin(__builtin_LINE))
160 ) noexcept;
161
169 [[nodiscard]] constexpr auto
170 file_name (void) const noexcept;
171
179 [[nodiscard]] constexpr auto
180 line (void) const noexcept;
181
182 private:
189 const char* file_{ "unknown" };
190
197 unsigned int line_{};
198 };
199
200#endif // defined(__cpp_lib_source_location)
201
218 template <class T>
219 [[nodiscard]] constexpr auto
220 type_name (void) -> std::string_view;
221
222 // ------------------------------------------------------------------------
223 } // namespace reflection
224
225 // --------------------------------------------------------------------------
226} // namespace micro_os_plus::micro_test_plus
227
228#if defined(__GNUC__)
229#pragma GCC diagnostic pop
230#endif // defined(__GNUC__)
231
232// ----------------------------------------------------------------------------
233
234#endif // defined(__cplusplus)
235
236// ============================================================================
237// Templates, inlines & constexpr implementations.
238
240
241// ----------------------------------------------------------------------------
242
243#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_REFLECTION_H_
244
245// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.8 by Doxygen 1.18.0.