ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
assert.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_assert of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8#if ALIB_DEBUG
9
10/// This namespace exposes entities of module \alib_assert.
11ALIB_EXPORT namespace alib::assert {
12
13#if !DOXYGEN
14# if ALIB_SINGLE_THREADED && ALIB_EXT_LIB_THREADS_AVAILABLE
16# else
17inline void SingleThreaded() {} // optimized out
18# endif
19#endif
20
21
22#if ALIB_DEBUG_ASSERTION_PRINTABLES
23/// This is the implementation of the templated sibling method, which fetches the variadic
24/// templated printables of an \alib_assertion.<br>
25///
26/// Available only if the configuration macro #"ALIB_DEBUG_ASSERTION_PRINTABLES" is given.
27/// @param ci Source location of the assertion raised.
28/// @param args The arguments of the assertion message.
29ALIB_DLL void CheckArgsImpl( const CallerInfo& ci, const std::span<std::any>& args );
30
31/// This method is called by the assertion macros with \b any \alib invocation - hence regardless
32/// whether the assertion or warning was raised or not - in the case that the configuration macro
33/// #"ALIB_DEBUG_ASSERTION_PRINTABLES" is given.<br>
34/// This is used to ensure that all arguments passed are of
35/// #"RegisterPrintable;a known type".
36/// Otherwise, assertions that happen seldom would raise an inner assertion due to unsupported
37/// arguments.
38/// @tparam TArgs Types of the variadic arguments \p{args}.
39/// @param ci Source location of the assertion raised.
40/// @param args Variadic argument list comprising the assertion message, which are to be
41/// tested.
42template<typename... TArgs>
43void CheckArgs( const CallerInfo& ci, TArgs&&... args) {
44 constexpr size_t numArgs = sizeof...(TArgs);
45 if constexpr (numArgs > 0) {
46 std::any argArray[numArgs]= { std::forward<TArgs>(args)... };
47 CheckArgsImpl( ci, argArray );
48 }
49}
50#endif
51
52/// Embeds two flags that allow control of whether function #"Raise" halts on errors,
53/// respectively warnings.
54/// The default is to halt on errors, but not on warnings.<br>
55/// A thread-local instance is given (and internally tested) with the function
56/// #"GetHaltFlagAndCounters".
57///
58/// Note that this mechanism is mostly needed for unit-testing.
59/// Here, errors may need to be tested to be properly raised.
60struct TLD {
61
62 /// Flag to enable/disable the use of <c>assert(0)</c> when an \alib error was raised.
63 bool HaltOnErrors = true;
64
65 /// Flag to enable/disable the use of <c>assert(0)</c> when an \alib_warning was raised.
66 bool HaltOnWarnings = false;
67
68 /// The number of errors counted for this thread.
69 size_t CtdErrors = 0;
70
71 /// The number of warnings counted for this thread.
72 size_t CtdWarnings = 0;
73
74 /// The number of messages counted for this thread.
75 size_t CtdMessages = 0;
76};
77
78/// Returns the \c thread_local instance of flags and counters used by function
79/// #"alib::assert::Raise;3".
80/// @return The singleton, thread-local instance of the flags.
82
83
84/// A type alias for a function pointer that defines a high-level mechanism for appending a
85/// <c>std::any</c> value to a <c>std::string</c>.
86/// Custom functions may be registered using function #"RegisterPrintable".
87/// This then allows to use custom objects as "printables" in assertions.
88using AnyConversionFunc = void(*)(const std::any&, std::string&);
89
90/// A predefined format string used to generate consistent assertion messages.
91/// A goal here is to allow a user of \alib to change this format to have assertions, warnings,
92/// and messages in the IDE-console be clickable (to jump to the right source location).
93/// The default format works well with \https{JetBrains CLion,www.jetbrains.com/clion}.
94///
95/// Defaults to: <c>"{file}:{line} {type}:\\n{message}"</c>.
96///
97/// (With this default-value, the placeholder syntax should be self-explanatory.)
98ALIB_DLL extern std::string_view FORMAT;
99
100/// The output stream used to with function #"assert::Raise", when the parameter \p{type}
101/// equals \c 0.<br>
102/// Defaults to <c>std::err</c>.
103ALIB_DLL extern std::ostream* STREAM_ERRORS;
104
105/// The output stream used to with function #"assert::Raise", when the parameter \p{type}
106/// equals \c 1.<br>
107/// Defaults to <c>std::cout</c>.
108ALIB_DLL extern std::ostream* STREAM_WARNINGS;
109
110/// The output stream used to with function #"assert::Raise", when the parameter \p{type}
111/// does not equal \c 0 or \c 1.<br>
112/// Defaults to <c>std::cout</c>.
113ALIB_DLL extern std::ostream* STREAM_MESSAGES;
114
115/// Allows registering custom types to be printable with debug-function #"assert::Raise".
116/// The following snippet from the internal codebase that registers basic types as lambda
117/// functions demonstrates how this function can be called:
118///
119/// \snippet "assert.cpp" DOX_ASSERT_REGISTER_PRINTABLE
120/// @param typeIndex The type to register a conversion method for.
121/// @param func The conversion function.
122ALIB_DLL void RegisterPrintable(std::type_index typeIndex, AnyConversionFunc func);
123
124
125/// The implementation of sibling method #"Raise" that takes a variadic number of arguments.
126/// @param ci Caller information.
127/// @param type The type of the message: \c 0 for error, \c 1 for warning, higher values for
128/// messages.
129/// @param domain The domain of the assertion, warning, or message.
130/// (Usually the name of the \alibmod_nl.)
131/// Has to be capital alphanumeric letters.
132/// @param args The array of arguments.
133ALIB_DLL void raise( const lang::CallerInfo& ci, int type, std::string_view domain,
134 const std::span<std::any>& args );
135
136/// This method is used by \alib modules to raise assertions, warnings and display debug-messages.
137/// (The latter usually depends on special the configuration macros like #"ALIB_DEBUG_MEMORY".)
138///
139/// It may be used by custom code for custom assertions as well.
140///
141/// This method first checks if the function pointer #"assert::PLUGIN" is set
142/// and if yes, passes the parameters to this method and exits.
143///
144/// Otherwise, the method just writes to the standard error and output streams (which is changeable)
145/// and then, if \p{type} equals \c 0, invokes <c>assert(0)</c>.
146///
147/// @see
148/// The following entities are related to \alib_assertions:
149/// - Function #"raise" (called by this method after converting the variadic arguments to
150/// an array of <c>std::any</c> objects.
151/// - Type definition #"AnyConversionFunc" to register custom printable types.
152/// - Function #"RegisterPrintable" to register a conversion function.
153/// - Namespace variable #"assert::FORMAT" that defines the output format.
154/// - Namespace variables #"STREAM_ERRORS", #"STREAM_WARNINGS", and #"STREAM_MESSAGES" allowing
155/// to redirect assertion messages.
156/// - Thread-local struct HALT_FLAGS_AND_COUNTERS, which allows tweaking
157/// the assertion behavior and implements usage counters. (Mostly done to support unit-tests.)
158/// - Assertion and message macros:
159/// - ALIB_ERROR,
160/// - ALIB_WARNING,
161/// - ALIB_MESSAGE,
162/// - ALIB_ASSERT,
163/// - ALIB_ASSERT_ERROR,
164/// - ALIB_ASSERT_WARNING, and
165/// - ALIB_ASSERT_MESSAGE.
166/// - ALIB_ERROR,
167/// - ALIB_ERROR,
168///
169/// @tparam TArgs The types of the variadic function arguments \p{args}.
170/// @param ci Caller information.
171/// @param type The type of the message: \c 0 for error, \c 1 for warning, higher values for
172/// messages.
173/// @param domain The domain of the assertion, warning, or message.
174/// (Usually the name of the \alibmod_nl.)
175/// Has to be capital alphanumeric letters.
176/// @param args Variadic argument list comprising the message.
177template<typename... TArgs>
178void Raise( const lang::CallerInfo& ci, int type, std::string_view domain, TArgs&&... args) {
179 if constexpr (sizeof...(TArgs) == 0)
180 raise( ci, type, domain, std::span<std::any>{} );
181 else {
182 std::array<std::any, sizeof...(TArgs)> argArray { std::forward<TArgs>(args)... };
183 alib::assert::raise( ci, type, domain, argArray );
184} }
185
186/// This function pointer defaults to \c nullptr and may be set by from outside to redirect
187/// writing the assertion, warning or message text of the functions #"Raise", respectively
188/// #"raise".
189///
190/// With the use of module \alib_alox this pointer can be set to redirect the output to a
191/// #"%Lox". Further information on this is found with the chapter
192/// #"alib_mod_alox_debug_and_release_logging_ft_4" of the Programmer's Manual of module
193/// \alib_alox_nl.
194///
195/// - \p{ci}: Information about the scope of invocation.
196/// - \p{type}: The type of the message. As a convention, 0 is severe error, others are warning
197/// levels.
198/// - \p{domain}: Usually the name of the module that raised the assertion.
199/// - \p{msg}: The assembled message to print.
200extern void (*PLUGIN)( const lang::CallerInfo& ci,
201 int type,
202 std::string_view domain,
203 std::string_view msg );
204
205} // namespace [alib::assert]
206#endif // ALIB_DEBUG
#define ALIB_DLL
#define ALIB_EXPORT
This namespace exposes entities of module ALib Assert.
Definition assert.cpp:4
void CheckArgsImpl(const CallerInfo &ci, const std::span< std::any > &args)
void(* PLUGIN)(const CallerInfo &ci, int type, std::string_view domain, std::string_view msg)
Definition assert.cpp:70
std::string_view FORMAT
Definition assert.cpp:73
void Raise(const lang::CallerInfo &ci, int type, std::string_view domain, TArgs &&... args)
Definition assert.hpp:178
void RegisterPrintable(std::type_index typeIndex, AnyConversionFunc func)
std::ostream * STREAM_MESSAGES
Definition assert.cpp:76
void raise(const CallerInfo &ci, int type, std::string_view domain, const std::span< std::any > &args)
Definition assert.cpp:552
std::ostream * STREAM_ERRORS
Definition assert.cpp:74
void CheckArgs(const CallerInfo &ci, TArgs &&... args)
Definition assert.hpp:43
TLD & GetHaltFlagAndCounters()
Definition assert.cpp:550
std::ostream * STREAM_WARNINGS
Definition assert.cpp:75
void SingleThreaded()
Definition assert.cpp:39
void(*)(const std::any &, std::string &) AnyConversionFunc
Definition assert.hpp:88
lang::CallerInfo CallerInfo
Type alias in namespace #"%alib".
bool HaltOnErrors
Flag to enable/disable the use of assert(0) when an ALib error was raised.
Definition assert.hpp:63
bool HaltOnWarnings
Flag to enable/disable the use of assert(0) when an ALib Warning was raised.
Definition assert.hpp:66
size_t CtdWarnings
The number of warnings counted for this thread.
Definition assert.hpp:72
size_t CtdMessages
The number of messages counted for this thread.
Definition assert.hpp:75
size_t CtdErrors
The number of errors counted for this thread.
Definition assert.hpp:69