7171// compatibility, although we no longer use it in the library.
7272#include " libmesh/libmesh_nullptr.h"
7373
74+ // C++ headers
75+ #include < iomanip> // setprecision, in assertion macros
76+
7477namespace libMesh
7578{
7679namespace Threads
@@ -80,16 +83,26 @@ void lock_singleton_spin_mutex();
8083void unlock_singleton_spin_mutex ();
8184}
8285
86+ // Let's define a couple output streams - these will default
87+ // to cout/cerr, but LibMeshInit (or the user) can also set them to
88+ // something more sophisticated.
89+ //
90+ // We use a proxy class rather than references so they can be
91+ // reseated at runtime.
92+
93+ extern OStreamProxy out;
94+ extern OStreamProxy err;
95+
8396// A namespace for functions used in the bodies of the macros below.
8497// The macros generally call these functions with __FILE__, __LINE__,
8598// __DATE__, and __TIME__ in the appropriate order. These should not
8699// be called by users directly! The implementations can be found in
87100// libmesh_common.C.
88101namespace MacroFunctions
89102{
90- void here (const char * file, int line, const char * date, const char * time);
103+ void here (const char * file, int line, const char * date, const char * time, std::ostream & os = libMesh::err );
91104void stop (const char * file, int line, const char * date, const char * time);
92- void report_error (const char * file, int line, const char * date, const char * time);
105+ void report_error (const char * file, int line, const char * date, const char * time, std::ostream & os = libMesh::err );
93106}
94107
95108// Undefine any existing macros
@@ -221,16 +234,6 @@ extern MPI_Comm GLOBAL_COMM_WORLD;
221234extern int GLOBAL_COMM_WORLD;
222235#endif
223236
224- // Let's define a couple output streams - these will default
225- // to cout/cerr, but LibMeshInit (or the user) can also set them to
226- // something more sophisticated.
227- //
228- // We use a proxy class rather than references so they can be
229- // reseated at runtime.
230-
231- extern OStreamProxy out;
232- extern OStreamProxy err;
233-
234237// This global variable is to help us deprecate AutoPtr. We can't
235238// just use libmesh_deprecated() because then you get one print out
236239// per template instantiation, instead of one total print out.
@@ -308,76 +311,15 @@ extern bool warned_about_auto_ptr;
308311#define libmesh_assert_equal_to_msg (expr1,expr2, msg ) \
309312 do { \
310313 if (!((expr1) == (expr2))) { \
311- libMesh::Threads::lock_singleton_spin_mutex (); \
312- std::streamsize oldp = libMesh::err.precision (17 ); \
313- libMesh::err << " Assertion `" #expr1 " == " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
314- libMesh::err.precision (oldp); \
315- libMesh::Threads::unlock_singleton_spin_mutex (); \
316- libmesh_error (); \
314+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " == " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
317315 } } while (0 )
318316
319317#define libmesh_assert_not_equal_to_msg (expr1,expr2, msg ) \
320318 do { \
321319 if (!((expr1) != (expr2))) { \
322- libMesh::Threads::lock_singleton_spin_mutex (); \
323- std::streamsize oldp = libMesh::err.precision (17 ); \
324- libMesh::err << " Assertion `" #expr1 " != " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
325- libMesh::err.precision (oldp); \
326- libMesh::Threads::unlock_singleton_spin_mutex (); \
327- libmesh_error (); \
320+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " != " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
328321 } } while (0 )
329322
330- // Older Clang has a parsing bug that can't seem to handle the handle the decay statement when
331- // expanding these macros. We'll just fall back to the previous behavior with those older compilers
332- #if defined(__clang__) && (__clang_major__ <= 3)
333-
334- #define libmesh_assert_less_msg (expr1,expr2, msg ) \
335- do { \
336- if (!((expr1) < (expr2))) { \
337- libMesh::Threads::lock_singleton_spin_mutex (); \
338- std::streamsize oldp = libMesh::err.precision (17 ); \
339- libMesh::err << " Assertion `" #expr1 " < " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
340- libMesh::err.precision (oldp); \
341- libMesh::Threads::unlock_singleton_spin_mutex (); \
342- libmesh_error (); \
343- } } while (0 )
344-
345- #define libmesh_assert_greater_msg (expr1,expr2, msg ) \
346- do { \
347- if (!((expr1) > (expr2))) { \
348- libMesh::Threads::lock_singleton_spin_mutex (); \
349- std::streamsize oldp = libMesh::err.precision (17 ); \
350- libMesh::err << " Assertion `" #expr1 " > " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
351- libMesh::err.precision (oldp); \
352- libMesh::Threads::unlock_singleton_spin_mutex (); \
353- libmesh_error (); \
354- } } while (0 )
355-
356- #define libmesh_assert_less_equal_msg (expr1,expr2, msg ) \
357- do { \
358- if (!((expr1) <= (expr2))) { \
359- libMesh::Threads::lock_singleton_spin_mutex (); \
360- std::streamsize oldp = libMesh::err.precision (17 ); \
361- libMesh::err << " Assertion `" #expr1 " <= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
362- libMesh::err.precision (oldp); \
363- libMesh::Threads::unlock_singleton_spin_mutex (); \
364- libmesh_error (); \
365- } } while (0 )
366-
367- #define libmesh_assert_greater_equal_msg (expr1,expr2, msg ) \
368- do { \
369- if (!((expr1) >= (expr2))) { \
370- libMesh::Threads::lock_singleton_spin_mutex (); \
371- std::streamsize oldp = libMesh::err.precision (17 ); \
372- libMesh::err << " Assertion `" #expr1 " >= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
373- libMesh::err.precision (oldp); \
374- libMesh::Threads::unlock_singleton_spin_mutex (); \
375- libmesh_error (); \
376- } } while (0 )
377-
378- // Newer clangs and all other supported compilers
379- #else
380-
381323template <template <class > class Comp >
382324struct casting_compare {
383325
@@ -400,49 +342,27 @@ struct casting_compare {
400342#define libmesh_assert_less_msg (expr1,expr2, msg ) \
401343 do { \
402344 if (!libMesh::casting_compare<std::less>()(expr1, expr2)) { \
403- libMesh::Threads::lock_singleton_spin_mutex (); \
404- std::streamsize oldp = libMesh::err.precision (17 ); \
405- libMesh::err << " Assertion `" #expr1 " < " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
406- libMesh::err.precision (oldp); \
407- libMesh::Threads::unlock_singleton_spin_mutex (); \
408- libmesh_error (); \
345+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " < " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
409346 } } while (0 )
410347
411348#define libmesh_assert_greater_msg (expr1,expr2, msg ) \
412349 do { \
413350 if (!libMesh::casting_compare<std::greater>()(expr1, expr2)) { \
414- libMesh::Threads::lock_singleton_spin_mutex (); \
415- std::streamsize oldp = libMesh::err.precision (17 ); \
416- libMesh::err << " Assertion `" #expr1 " > " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
417- libMesh::err.precision (oldp); \
418- libMesh::Threads::unlock_singleton_spin_mutex (); \
419- libmesh_error (); \
351+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " > " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
420352 } } while (0 )
421353
422354#define libmesh_assert_less_equal_msg (expr1,expr2, msg ) \
423355 do { \
424356 if (!libMesh::casting_compare<std::less_equal>()(expr1, expr2)) { \
425- libMesh::Threads::lock_singleton_spin_mutex (); \
426- std::streamsize oldp = libMesh::err.precision (17 ); \
427- libMesh::err << " Assertion `" #expr1 " <= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
428- libMesh::err.precision (oldp); \
429- libMesh::Threads::unlock_singleton_spin_mutex (); \
430- libmesh_error (); \
357+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " <= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
431358 } } while (0 )
432359
433360#define libmesh_assert_greater_equal_msg (expr1,expr2, msg ) \
434361 do { \
435362 if (!libMesh::casting_compare<std::greater_equal>()(expr1, expr2)) { \
436- libMesh::Threads::lock_singleton_spin_mutex (); \
437- std::streamsize oldp = libMesh::err.precision (17 ); \
438- libMesh::err << " Assertion `" #expr1 " >= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl; \
439- libMesh::err.precision (oldp); \
440- libMesh::Threads::unlock_singleton_spin_mutex (); \
441- libmesh_error (); \
363+ libmesh_error_msg (std::setprecision (17 ) << " Assertion `" #expr1 " >= " #expr2 " ' failed.\n " #expr1 " = " << (expr1) << " \n " #expr2 " = " << (expr2) << ' \n ' << msg << std::endl); \
442364 } } while (0 )
443365
444- #endif // clang <4.0
445-
446366#endif
447367
448368
@@ -468,13 +388,12 @@ struct casting_compare {
468388// throws a ConvergenceFailure exception
469389#define libmesh_error_msg (msg ) \
470390 do { \
391+ std::stringstream message_stream; \
392+ message_stream << msg << ' \n ' ; \
471393 libMesh::Threads::lock_singleton_spin_mutex (); \
472- libMesh::err << msg << std::endl; \
473- std::stringstream msg_stream; \
474- msg_stream << msg; \
475- libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); \
394+ libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
476395 libMesh::Threads::unlock_singleton_spin_mutex (); \
477- LIBMESH_THROW (libMesh::LogicError (msg_stream .str ())); \
396+ LIBMESH_THROW (libMesh::LogicError (message_stream .str ())); \
478397 } while (0 )
479398
480399#define libmesh_error () libmesh_error_msg(" " )
@@ -488,7 +407,7 @@ struct casting_compare {
488407#define libmesh_exceptionless_error_msg (msg ) \
489408 do { \
490409 libMesh::Threads::lock_singleton_spin_mutex (); \
491- libMesh::err << msg << std::endl; \
410+ libMesh::err << msg << ' \n ' ; \
492411 libmesh_try { libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); } \
493412 libmesh_catch (...) {} \
494413 libMesh::Threads::unlock_singleton_spin_mutex (); \
@@ -499,23 +418,24 @@ struct casting_compare {
499418
500419#define libmesh_not_implemented_msg (msg ) \
501420 do { \
421+ std::stringstream message_stream; \
422+ message_stream << msg << ' \n ' ; \
502423 libMesh::Threads::lock_singleton_spin_mutex (); \
503- libMesh::err << msg << std::endl; \
504- libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); \
424+ libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
505425 libMesh::Threads::unlock_singleton_spin_mutex (); \
506- LIBMESH_THROW (libMesh::NotImplemented ()); \
426+ LIBMESH_THROW (libMesh::NotImplemented (message_stream. str ())); \
507427 } while (0 )
508428
509429#define libmesh_not_implemented () libmesh_not_implemented_msg(" " )
510430
511431#define libmesh_file_error_msg (filename, msg ) \
512432 do { \
433+ std::stringstream message_stream; \
434+ message_stream << msg << ' \n ' ; \
513435 libMesh::Threads::lock_singleton_spin_mutex (); \
514- libMesh::err << " Error with file `" << filename << " '" << std::endl; \
515- libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME); \
516- libMesh::err << msg << std::endl; \
436+ libMesh::MacroFunctions::report_error (__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \
517437 libMesh::Threads::unlock_singleton_spin_mutex (); \
518- LIBMESH_THROW (libMesh::FileError (filename)); \
438+ LIBMESH_THROW (libMesh::FileError (filename, message_stream. str ())); \
519439 } while (0 )
520440
521441#define libmesh_file_error (filename ) libmesh_file_error_msg(filename," " )
0 commit comments