Changeset 108:889d0c289d19 in lemon-1.2 for lemon/error.h
- Timestamp:
- 03/25/08 16:36:44 (17 years ago)
- Branch:
- default
- Children:
- 109:abddaa08b507, 112:d2ee5e7f00ef
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/error.h
r66 r108 94 94 }; 95 95 96 /// Exception-safe convenient "error message"class.96 /// Exception-safe convenient error message builder class. 97 97 98 98 /// Helper class which provides a convenient ostream-like (operator << … … 414 414 }; 415 415 416 417 ///\e 418 class AssertionFailedError : public LogicError { 419 protected: 420 const char *assertion; 421 const char *file; 422 int line; 423 const char *function; 424 const char *message; 425 426 mutable ExceptionMember<std::string> _message_holder; 427 public: 428 ///\e 429 AssertionFailedError(const char *_file, int _line, const char *func, 430 const char *msg, const char *_assertion = 0) : 431 assertion(_assertion), file(_file), line(_line), function(func), 432 message(msg) {} 433 434 ///\e 435 const char* get_assertion() const { return assertion; } 436 ///\e 437 const char* get_message() const { return message; } 438 ///\e 439 const char* get_file() const { return file; } 440 ///\e 441 const char* get_function() const { return function; } 442 ///\e 443 int get_line() const { return line; } 444 445 446 virtual const char* what() const throw() { 447 try { 448 std::ostringstream ostr; 449 ostr << file << ":" << line << ": "; 450 if( function ) 451 ostr << function << ": "; 452 ostr << message; 453 if( assertion ) 454 ostr << " (assertion '" << assertion << "' failed)"; 455 _message_holder.set(ostr.str()); 456 return ostr.str().c_str(); 457 } 458 catch(...) {} 459 if( _message_holder.valid() ) return _message_holder.get().c_str(); 460 return "lemon::AssertionFailedError"; 461 } 462 virtual ~AssertionFailedError() throw() {} 463 }; 464 465 466 /**************** Macros ****************/ 467 468 469 template <typename Exception> 470 inline void assert_fail(const char *file, int line, 471 const char *func, 472 Exception exception, 473 const char *assertion = 0, 474 bool do_abort=true) 475 { 476 using namespace std; 477 cerr << file << ":" << line << ": "; 478 if (func) 479 cerr << func << ": "; 480 cerr << exception.what(); 481 if (assertion) 482 cerr << " (assertion '" << assertion << "' failed)"; 483 cerr << endl; 484 if (do_abort) 485 abort(); 486 } 487 488 template <> 489 inline void assert_fail<const char *>(const char *file, int line, 490 const char *func, 491 const char *message, 492 const char *assertion, 493 bool do_abort) 494 { 495 using namespace std; 496 cerr << file << ":" << line << ": "; 497 if (func) 498 cerr << func << ": "; 499 cerr << message; 500 if (assertion) 501 cerr << " (assertion '" << assertion << "' failed)"; 502 cerr << endl; 503 if (do_abort) 504 abort(); 505 } 506 507 template <> 508 inline void assert_fail<std::string>(const char *file, int line, 509 const char *func, 510 std::string message, 511 const char *assertion, 512 bool do_abort) 513 { 514 assert_fail(file, line, func, message.c_str(), assertion, do_abort); 515 } 516 517 template <typename Exception> 518 inline void assert_fail_failure(const char *file, int line, const char *func, 519 Exception exception, 520 const char *assertion = 0, 521 bool = true) 522 { 523 throw AssertionFailedError(file, line, func, exception.what(), assertion); 524 } 525 526 template <> 527 inline void assert_fail_failure<const char *>(const char *file, int line, 528 const char *func, 529 const char *message, 530 const char *assertion, 531 bool) 532 { 533 throw AssertionFailedError(file, line, func, message, assertion); 534 } 535 536 template <> 537 inline void assert_fail_failure<std::string>(const char *file, int line, 538 const char *func, 539 std::string message, 540 const char *assertion, 541 bool) 542 { 543 assert_fail_failure(file, line, func, message.c_str(), assertion, true); 544 } 545 546 template <typename Exception> 547 inline void assert_fail_exception(const char *file, int line, const char *func, 548 Exception exception, 549 const char *assertion = 0, bool = true) 550 { 551 throw exception; 552 } 553 554 template <> 555 inline void assert_fail_exception<const char *>(const char *file, int line, 556 const char *func, 557 const char *message, 558 const char *assertion, 559 bool) 560 { 561 throw AssertionFailedError(file, line, func, message, assertion); 562 } 563 564 template <> 565 inline void assert_fail_exception<std::string>(const char *file, int line, 566 const char *func, 567 std::string message, 568 const char *assertion, 569 bool) 570 { 571 assert_fail_exception(file, line, func, message.c_str(), assertion, true); 572 } 573 574 /// @} 416 /// @} 575 417 576 418 } 419 577 420 #endif // LEMON_ERROR_H 578 579 #undef LEMON_ASSERT580 #undef LEMON_FIXME581 582 #ifdef LEMON_ENABLE_ASSERTS583 # define LEMON_ASSERT_ABORT584 #endif585 586 #ifndef LEMON_ASSERT_DO_ABORT587 # define LEMON_ASSERT_DO_ABORT 1588 #endif589 590 #ifndef LEMON_ASSERT_HANDLER591 # if defined LEMON_ASSERT_EXCEPTION592 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception593 # elif defined LEMON_ASSERT_FAILURE594 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure595 # elif defined LEMON_ASSERT_ABORT596 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail597 # else598 # define LEMON_DISABLE_ASSERTS599 # endif600 #endif601 602 #ifdef DOXYGEN603 604 /// \brief Macro for assertions with customizable message605 ///606 /// Macro for assertions with customizable message.607 ///608 /// The assertions are disabled in the default behaviour. You can609 /// enable the assertions with the610 /// \code611 /// #define LEMON_ENABLE_ASSERTS612 /// \endcode613 /// Then an assert614 /// provides a log on the standard error about the assertion and aborts615 /// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the616 /// program keeps on running).617 /// By defining LEMON_ASSERT_FAILURE or618 /// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the619 /// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT620 /// will always throw an \c AssertionFailedError exception with621 /// the \c msg error message. By using622 /// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.623 ///624 /// The LEMON_ASSERT macro should be called with the \c exp parameter625 /// which should be an expression convertible to bool. If the given626 /// parameter is false the assertion is raised and one of the assertion627 /// behaviour will be activated. The \c msg should be either a const628 /// char* message or an exception. When the \c msg is an exception the629 /// \ref lemon::Exception::what() "what()" function is called to retrieve and630 /// display the error message.631 ///632 /// \todo We should provide some way to reset to the default behaviour,633 /// shouldn't we?634 ///635 /// \todo This whole 'assert' business should be placed in a separate636 /// include file. The boost assert is not guarded by header sentries637 /// which may help to change the behaviour of the assertions in638 /// the files.639 ///640 /// \todo __PRETTY_FUNCTION__ should be replaced by something641 /// compiler-independent, like BOOST_CURRENT_FUNCTION642 643 # define LEMON_ASSERT(exp, msg) \644 (static_cast<void> (!!(exp) ? 0 : ( \645 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \646 __PRETTY_FUNCTION__, \647 msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))648 649 #else650 # if defined LEMON_DISABLE_ASSERTS651 652 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))653 654 # else655 # define LEMON_ASSERT(exp, msg) \656 (static_cast<void> (!!(exp) ? 0 : ( \657 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \658 __PRETTY_FUNCTION__, \659 msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))660 # endif661 #endif662 663 /**664 * \brief Macro for mark not yet implemented features.665 *666 * \todo Is this the right place for this? It should be used only in667 * modules under development.668 *669 * \todo __PRETTY_FUNCTION__ should be replaced by something670 * compiler-independent, like BOOST_CURRENT_FUNCTION671 */672 673 #define LEMON_FIXME(msg) \674 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \675 "FIXME: " msg))
Note: See TracChangeset
for help on using the changeset viewer.