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