BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
assert.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_ASSERT_HPP
13#define BELFEM_ASSERT_HPP
14
15#include <sstream>
16#include <stdexcept>
17#include <vector>
18
19#include "typedefs.hpp"
20#include "fn_sprint.hpp"
21
22//------------------------------------------------------------------------------
23
24// Whether BELFEM_ASSERT expands to a check at all. Owned by this header: tests
25// that exercise an assertion-tier error path must guard on this macro rather
26// than restate the condition as #ifndef NDEBUG, which is not equivalent when
27// both NDEBUG and DEBUG are defined.
28#if !defined( NDEBUG ) || defined( DEBUG )
29#define BELFEM_ASSERTIONS_ACTIVE 1
30#else
31#define BELFEM_ASSERTIONS_ACTIVE 0
32#endif
33
34//------------------------------------------------------------------------------
35
36namespace belfem
37{
38 namespace assert
39 {
40
41//------------------------------------------------------------------------------
42
43 std::vector<std::string>
44 wrap_lines(std::size_t aMaxWidth, const std::string & aLine);
45
46//------------------------------------------------------------------------------
47
48 void
49 hatch_dragon( std::vector< std::string > & aDragon ) ;
50
51//------------------------------------------------------------------------------
52
53 void
54 print_line(const std::vector<std::string> & aDragon, std::size_t & aCounter );
55
56//------------------------------------------------------------------------------
57
58 void
59 print_line( const std::vector<std::string> & aDragon,
60 const string & aLine, std::size_t & aCounter );
61
62//------------------------------------------------------------------------------
63
64 void
65 print_line( const string & aLine );
66
67//------------------------------------------------------------------------------
68
69 void
70 get_lines( const string & aWhat, std::vector< std::string > & aLines );
71
72//------------------------------------------------------------------------------
73
74 void
76 const std::string & aLocation,
77 const std::string & aTask,
78 const std::string & aCheck,
79 const std::vector< std::string > & aMessage ) ;
80
81//------------------------------------------------------------------------------
82
83 void
85
86//------------------------------------------------------------------------------
87
119 bool
121
122 void
123 set_throw_on_error( const bool aValue );
124
125
126//------------------------------------------------------------------------------
127
139 bool
141
142 void
143 set_syslog_on_error( const bool aValue );
144
150 void
152 const std::string & aLocation,
153 const std::string & aCheck,
154 const std::vector< std::string > & aMessage );
155
156//------------------------------------------------------------------------------
157
158 template< typename Exception >
159 void
161 const std::string & aLocation,
162 const std::string & aTask,
163 const std::string & aCheck,
164 const Exception & aException = Exception()
165 )
166 {
167
168 std::istringstream tExceptionMessage( aException.what() );
169 std::string tExceptionLine ;
170
171
172 std::vector< std::string > tMessage ;
173 while ( std::getline( tExceptionMessage, tExceptionLine) )
174 {
175 tMessage.push_back( tExceptionLine );
176 }
177
178 print_errorbox( aLocation, aTask, aCheck, tMessage );
179
180 // the syslog hook sits before the reaction branch, and it must
181 // stay there: a debug build still throws ( that is the daily gdb /
182 // make check path, serial or parallel ), so an abort-only
183 // placement would go silent exactly where a developer reads the
184 // message
185 if ( syslog_on_error() )
186 {
187 log_to_syslog( aLocation, aCheck, tMessage );
188 }
189
190 if ( throw_on_error() )
191 {
192 throw aException;
193 }
194
195 error_abort();
196 }
197
198//------------------------------------------------------------------------------
199
200 std::string
201 extract_function_name( const std::string & aPrettyFunction );
202
203//------------------------------------------------------------------------------
204
205 template < typename ... Args >
206 void
208 const std::string & aFile,
209 const std::size_t & aLine,
210 const std::string & aFunction,
211 const std::string & aCheck,
212 const Args ... aArgs )
213 {
214 std::stringstream tLocation;
215
216 // get the basename (deliberately not including stringtools here)
217 // find last entry of directory delimeter
218 tLocation << aFile.substr( aFile.find_last_of("/\\") + 1 ) << " (line " << aLine << ")";
219
220 std::stringstream tTask;
221 tTask << "complete call to function " << extract_function_name( aFunction ) << "()";
222
223 std::stringstream tReason;
224 tReason << "Assertion " << aCheck << " failed.";
225
226 // format output message
227 std::string tMessage = belfem::sprint( aArgs ... );
228
230 tLocation.str(),
231 tTask.str(),
232 tReason.str(),
233 std::runtime_error( tMessage.c_str() ) );
234 }
235
236
237//------------------------------------------------------------------------------
238 } /* namespace assert */
239} /* namespace belfem */
240
241//------------------------------------------------------------------------------
242
243#if BELFEM_ASSERTIONS_ACTIVE
244#define BELFEM_ASSERT( aCheck, ... ) \
245 do \
246 { \
247 if ( ! ( aCheck ) ) \
248 { \
249 belfem::assert::belfem_assert( \
250 __FILE__, \
251 __LINE__, \
252 __PRETTY_FUNCTION__, \
253 #aCheck, \
254 __VA_ARGS__ \
255 ); \
256 } \
257 } while ( false )
258#else
259#define BELFEM_ASSERT( aCheck, ... )
260#endif
261
262//---------------------------------------------------------------------------
263
264#define BELFEM_ERROR( aCheck, ... ) \
265 do \
266 { \
267 if ( ! ( aCheck ) ) \
268 { \
269 belfem::assert::belfem_assert( \
270 __FILE__, \
271 __LINE__, \
272 __PRETTY_FUNCTION__, \
273 #aCheck, \
274 __VA_ARGS__ \
275 ); \
276 } \
277 } while ( false )
278
279//------------------------------------------------------------------------------
280
281#endif //BELFEM_ASSERT_HPP
void error(const std::string &aLocation, const std::string &aTask, const std::string &aCheck, const Exception &aException=Exception())
Definition assert.hpp:160
void get_lines(const string &aWhat, std::vector< std::string > &aLines)
Definition assert.cpp:222
bool syslog_on_error()
Whether a failed check also writes its message to the system log ( syslog, identity "belfem",...
Definition assert.cpp:338
void print_line(const std::vector< std::string > &aDragon, std::size_t &aCounter)
Definition assert.cpp:174
void error_abort()
Definition assert.cpp:295
std::string extract_function_name(const std::string &aPrettyFunction)
Definition assert.cpp:36
void set_throw_on_error(const bool aValue)
Definition assert.cpp:325
void belfem_assert(const std::string &aFile, const std::size_t &aLine, const std::string &aFunction, const std::string &aCheck, const Args ... aArgs)
Definition assert.hpp:207
void print_errorbox(const std::string &aLocation, const std::string &aTask, const std::string &aCheck, const std::vector< std::string > &aMessage)
Definition assert.cpp:237
std::vector< std::string > wrap_lines(std::size_t aMaxWidth, const std::string &aLine)
Definition assert.cpp:78
void log_to_syslog(const std::string &aLocation, const std::string &aCheck, const std::vector< std::string > &aMessage)
Definition assert.cpp:354
void set_syslog_on_error(const bool aValue)
Definition assert.cpp:346
void hatch_dragon(std::vector< std::string > &aDragon)
Definition assert.cpp:148
bool throw_on_error()
How a failed check reacts: true throws the exception, false calls error_abort().
Definition assert.cpp:317
USER GUIDES:
Definition cl_Capacitor.cpp:16
std::string sprint(const char *aFormat, const Args ... aArgs)
A format script similar to write( , ) in fortran.
Definition fn_sprint.hpp:44