123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- #ifndef BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
- #define BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
- // Copyright (C) 2008-2018 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0 (see accompanying
- // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
- // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
- // IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
- // .cpp does not need recompiling if config changes (recompile only user code).
- #include <boost/contract/core/exception.hpp>
- #include <boost/contract/detail/static_local_var.hpp>
- #include <boost/contract/detail/declspec.hpp>
- #include <boost/thread/lock_guard.hpp>
- #include <boost/thread/mutex.hpp>
- #include <boost/exception/diagnostic_information.hpp>
- #include <boost/config.hpp>
- #include <string>
- #include <sstream>
- #include <iostream>
- #include <exception>
- namespace boost { namespace contract {
- BOOST_CONTRACT_DETAIL_DECLINLINE
- exception::~exception() BOOST_NOEXCEPT_OR_NOTHROW {}
- BOOST_CONTRACT_DETAIL_DECLINLINE
- bad_virtual_result_cast::bad_virtual_result_cast(char const* from_type_name,
- char const* to_type_name) {
- std::ostringstream text;
- text
- << "incompatible contracted virtual function result type "
- << "conversion from '" << from_type_name << "' to '"
- << to_type_name << "'"
- ;
- what_ = text.str();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- bad_virtual_result_cast::~bad_virtual_result_cast() BOOST_NOEXCEPT_OR_NOTHROW {}
- BOOST_CONTRACT_DETAIL_DECLINLINE
- char const* bad_virtual_result_cast::what() const BOOST_NOEXCEPT_OR_NOTHROW {
- return what_.c_str();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- assertion_failure::assertion_failure(char const* const file,
- unsigned long const line, char const* const code) :
- file_(file), line_(line), code_(code)
- { init(); }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- assertion_failure::assertion_failure(char const* const code) :
- file_(""), line_(0), code_(code)
- { init(); }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- assertion_failure::~assertion_failure() BOOST_NOEXCEPT_OR_NOTHROW {}
- BOOST_CONTRACT_DETAIL_DECLINLINE
- char const* assertion_failure::what() const BOOST_NOEXCEPT_OR_NOTHROW {
- return what_.c_str();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- char const* assertion_failure::file() const { return file_; }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- unsigned long assertion_failure::line() const { return line_; }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- char const* assertion_failure::code() const { return code_; }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void assertion_failure::init() {
- std::ostringstream text;
- text << "assertion";
- if(std::string(code_) != "") text << " \"" << code_ << "\"";
- text << " failed";
- if(std::string(file_) != "") {
- text << ": file \"" << file_ << "\"";
- if(line_ != 0) text << ", line " << line_;
- }
- what_ = text.str();
- }
- namespace exception_ {
- enum failure_key {
- check_failure_key,
- pre_failure_key,
- post_failure_key,
- except_failure_key,
- old_failure_key,
- entry_inv_failure_key,
- exit_inv_failure_key
- };
- template<failure_key Key>
- void default_handler() {
- std::string k = "";
- switch(Key) {
- case check_failure_key: k = "check "; break;
- case pre_failure_key: k = "precondition "; break;
- case post_failure_key: k = "postcondition "; break;
- case except_failure_key: k = "except "; break;
- case old_failure_key: k = "old copy "; break;
- case entry_inv_failure_key: k = "entry invariant "; break;
- case exit_inv_failure_key: k = "exit invariant "; break;
- // No default (so compiler warning/error on missing enum case).
- }
- try { throw; }
- catch(boost::contract::assertion_failure const& error) {
- // what = "assertion '...' failed: ...".
- std::cerr << k << error.what() << std::endl;
- } catch(...) { // old_failure_key prints this, not above.
- std::cerr << k << "threw following exception:" << std::endl
- << boost::current_exception_diagnostic_information();
- }
- std::terminate(); // Default handlers log and call terminate.
- }
-
- template<failure_key Key>
- void default_from_handler(from) { default_handler<Key>(); }
- // Check failure.
- struct check_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<check_failure_mutex_tag,
- boost::mutex> check_failure_mutex;
- struct check_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- check_failure_handler_tag,
- failure_handler,
- void (*)(),
- &default_handler<check_failure_key>
- > check_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- failure_handler const& set_check_failure_unlocked(failure_handler const& f)
- BOOST_NOEXCEPT_OR_NOTHROW {
- check_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- failure_handler const& set_check_failure_locked(failure_handler const& f)
- BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
- return set_check_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- failure_handler get_check_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
- return check_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- failure_handler get_check_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
- return get_check_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void check_failure_unlocked() /* can throw */ {
- check_failure_handler::ref()();
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void check_failure_locked() /* can throw */ {
- boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
- check_failure_unlocked();
- }
-
- // Precondition failure.
- struct pre_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<pre_failure_mutex_tag,
- boost::mutex> pre_failure_mutex;
- struct pre_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- pre_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<pre_failure_key>
- > pre_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_pre_failure_unlocked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- pre_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_pre_failure_locked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
- return set_pre_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_pre_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
- return pre_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_pre_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
- return get_pre_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void pre_failure_unlocked(from where) /* can throw */ {
- pre_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void pre_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
- pre_failure_unlocked(where);
- }
-
- // Postcondition failure.
- struct post_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<post_failure_mutex_tag,
- boost::mutex> post_failure_mutex;
- struct post_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- post_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<post_failure_key>
- > post_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_post_failure_unlocked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- post_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_post_failure_locked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
- return set_post_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_post_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
- return post_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_post_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
- return get_post_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void post_failure_unlocked(from where) /* can throw */ {
- post_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void post_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
- post_failure_unlocked(where);
- }
-
- // Except failure.
- struct except_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<except_failure_mutex_tag,
- boost::mutex> except_failure_mutex;
- struct except_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- except_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<except_failure_key>
- > except_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_except_failure_unlocked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- except_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_except_failure_locked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
- return set_except_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_except_failure_unlocked()
- BOOST_NOEXCEPT_OR_NOTHROW {
- return except_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_except_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
- return get_except_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void except_failure_unlocked(from where) /* can throw */ {
- except_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void except_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
- except_failure_unlocked(where);
- }
- // Old-copy failure.
- struct old_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<old_failure_mutex_tag,
- boost::mutex> old_failure_mutex;
- struct old_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- old_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<old_failure_key>
- > old_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_old_failure_unlocked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- old_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_old_failure_locked(from_failure_handler
- const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
- return set_old_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_old_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
- return old_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_old_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
- return get_old_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void old_failure_unlocked(from where) /* can throw */ {
- old_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void old_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
- old_failure_unlocked(where);
- }
-
- // Entry invariant failure.
- struct entry_inv_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<
- entry_inv_failure_mutex_tag, boost::mutex> entry_inv_failure_mutex;
- struct entry_inv_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- entry_inv_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<entry_inv_failure_key>
- > entry_inv_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_entry_inv_failure_unlocked(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- entry_inv_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_entry_inv_failure_locked(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
- return set_entry_inv_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_entry_inv_failure_unlocked()
- BOOST_NOEXCEPT_OR_NOTHROW {
- return entry_inv_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_entry_inv_failure_locked()
- BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
- return get_entry_inv_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void entry_inv_failure_unlocked(from where) /* can throw */ {
- entry_inv_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void entry_inv_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
- entry_inv_failure_unlocked(where);
- }
-
- // Exit invariant failure.
- struct exit_inv_failure_mutex_tag;
- typedef boost::contract::detail::static_local_var<
- exit_inv_failure_mutex_tag, boost::mutex> exit_inv_failure_mutex;
- struct exit_inv_failure_handler_tag;
- typedef boost::contract::detail::static_local_var_init<
- exit_inv_failure_handler_tag,
- from_failure_handler,
- void (*)(from),
- &default_from_handler<exit_inv_failure_key>
- > exit_inv_failure_handler;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_exit_inv_failure_unlocked(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- exit_inv_failure_handler::ref() = f;
- return f;
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_exit_inv_failure_locked(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
- return set_exit_inv_failure_unlocked(f);
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_exit_inv_failure_unlocked()
- BOOST_NOEXCEPT_OR_NOTHROW {
- return exit_inv_failure_handler::ref();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler get_exit_inv_failure_locked()
- BOOST_NOEXCEPT_OR_NOTHROW {
- boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
- return get_exit_inv_failure_unlocked();
- }
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void exit_inv_failure_unlocked(from where) /* can throw */ {
- exit_inv_failure_handler::ref()(where);
- }
-
- BOOST_CONTRACT_DETAIL_DECLINLINE
- void exit_inv_failure_locked(from where) /* can throw */ {
- boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
- exit_inv_failure_unlocked(where);
- }
- }
- from_failure_handler const& set_entry_invariant_failure(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
- from_failure_handler const& set_exit_invariant_failure(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
- BOOST_CONTRACT_DETAIL_DECLINLINE
- from_failure_handler const& set_invariant_failure(
- from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- set_entry_invariant_failure(f);
- set_exit_invariant_failure(f);
- return f;
- }
- } } // namespace
- #endif // #include guard
|