Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:02

0001 
0002 #ifndef BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
0003 #define BOOST_CONTRACT_DETAIL_INLINED_EXCEPTION_HPP_
0004 
0005 // Copyright (C) 2008-2018 Lorenzo Caminiti
0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying
0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
0009 
0010 // IMPORTANT: Do NOT use config macros BOOST_CONTRACT_... in this file so lib
0011 // .cpp does not need recompiling if config changes (recompile only user code).
0012 
0013 #include <boost/contract/core/exception.hpp>
0014 #include <boost/contract/detail/static_local_var.hpp>
0015 #include <boost/contract/detail/declspec.hpp>
0016 #include <boost/thread/lock_guard.hpp>
0017 #include <boost/thread/mutex.hpp>
0018 #include <boost/exception/diagnostic_information.hpp>
0019 #include <boost/config.hpp>
0020 #include <string>
0021 #include <sstream>
0022 #include <iostream>
0023 #include <exception>
0024 
0025 namespace boost { namespace contract {
0026 
0027 BOOST_CONTRACT_DETAIL_DECLINLINE
0028 exception::~exception() BOOST_NOEXCEPT_OR_NOTHROW {}
0029 
0030 BOOST_CONTRACT_DETAIL_DECLINLINE
0031 bad_virtual_result_cast::bad_virtual_result_cast(char const* from_type_name,
0032             char const* to_type_name) {
0033     std::ostringstream text;
0034     text
0035         << "incompatible contracted virtual function result type "
0036         << "conversion from '" << from_type_name << "' to '"
0037         << to_type_name  << "'"
0038     ;
0039     what_ = text.str();
0040 }
0041 
0042 BOOST_CONTRACT_DETAIL_DECLINLINE
0043 bad_virtual_result_cast::~bad_virtual_result_cast() BOOST_NOEXCEPT_OR_NOTHROW {}
0044 
0045 BOOST_CONTRACT_DETAIL_DECLINLINE
0046 char const* bad_virtual_result_cast::what() const BOOST_NOEXCEPT_OR_NOTHROW {
0047     return what_.c_str();
0048 }
0049 
0050 BOOST_CONTRACT_DETAIL_DECLINLINE
0051 assertion_failure::assertion_failure(char const* const file,
0052         unsigned long const line, char const* const code) :
0053     file_(file), line_(line), code_(code)
0054 { init(); }
0055 
0056 BOOST_CONTRACT_DETAIL_DECLINLINE
0057 assertion_failure::assertion_failure(char const* const code) :
0058     file_(""), line_(0), code_(code)
0059 { init(); }
0060 
0061 BOOST_CONTRACT_DETAIL_DECLINLINE
0062 assertion_failure::~assertion_failure() BOOST_NOEXCEPT_OR_NOTHROW {}
0063 
0064 BOOST_CONTRACT_DETAIL_DECLINLINE
0065 char const* assertion_failure::what() const BOOST_NOEXCEPT_OR_NOTHROW {
0066     return what_.c_str();
0067 }
0068 
0069 BOOST_CONTRACT_DETAIL_DECLINLINE
0070 char const* assertion_failure::file() const { return file_; }
0071 
0072 BOOST_CONTRACT_DETAIL_DECLINLINE
0073 unsigned long assertion_failure::line() const { return line_; }
0074 
0075 BOOST_CONTRACT_DETAIL_DECLINLINE
0076 char const* assertion_failure::code() const { return code_; }
0077 
0078 BOOST_CONTRACT_DETAIL_DECLINLINE
0079 void assertion_failure::init() {
0080     std::ostringstream text;
0081     text << "assertion";
0082     if(std::string(code_) != "") text << " \"" << code_ << "\"";
0083     text << " failed";
0084     if(std::string(file_) != "") {
0085         text << ": file \"" << file_ << "\"";
0086         if(line_ != 0) text << ", line " << line_;
0087     }
0088     what_ = text.str();
0089 }
0090 
0091 namespace exception_ {
0092     enum failure_key {
0093         check_failure_key,
0094         pre_failure_key,
0095         post_failure_key,
0096         except_failure_key,
0097         old_failure_key,
0098         entry_inv_failure_key,
0099         exit_inv_failure_key
0100     };
0101 
0102     template<failure_key Key>
0103     void default_handler() {
0104         std::string k = "";
0105         switch(Key) {
0106             case check_failure_key: k = "check "; break;
0107             case pre_failure_key: k = "precondition "; break;
0108             case post_failure_key: k = "postcondition "; break;
0109             case except_failure_key: k = "except "; break;
0110             case old_failure_key: k = "old copy "; break;
0111             case entry_inv_failure_key: k = "entry invariant "; break;
0112             case exit_inv_failure_key: k = "exit invariant "; break;
0113             // No default (so compiler warning/error on missing enum case).
0114         }
0115         try { throw; }
0116         catch(boost::contract::assertion_failure const& error) {
0117             // what = "assertion '...' failed: ...".
0118             std::cerr << k << error.what() << std::endl;
0119         } catch(...) { // old_failure_key prints this, not above.
0120             std::cerr << k << "threw following exception:" << std::endl
0121                     << boost::current_exception_diagnostic_information();
0122         }
0123         std::terminate(); // Default handlers log and call terminate.
0124     }
0125     
0126     template<failure_key Key>
0127     void default_from_handler(from) { default_handler<Key>(); }
0128 
0129     // Check failure.
0130 
0131     struct check_failure_mutex_tag;
0132     typedef boost::contract::detail::static_local_var<check_failure_mutex_tag,
0133             boost::mutex> check_failure_mutex;
0134 
0135     struct check_failure_handler_tag;
0136     typedef boost::contract::detail::static_local_var_init<
0137         check_failure_handler_tag,
0138         failure_handler, 
0139         void (*)(),
0140         &default_handler<check_failure_key>
0141     > check_failure_handler;
0142 
0143     BOOST_CONTRACT_DETAIL_DECLINLINE
0144     failure_handler const& set_check_failure_unlocked(failure_handler const& f)
0145             BOOST_NOEXCEPT_OR_NOTHROW {
0146         check_failure_handler::ref() = f;
0147         return f;
0148     }
0149     
0150     BOOST_CONTRACT_DETAIL_DECLINLINE
0151     failure_handler const& set_check_failure_locked(failure_handler const& f)
0152             BOOST_NOEXCEPT_OR_NOTHROW {
0153         boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
0154         return set_check_failure_unlocked(f);
0155     }
0156 
0157     BOOST_CONTRACT_DETAIL_DECLINLINE
0158     failure_handler get_check_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
0159         return check_failure_handler::ref();
0160     }
0161 
0162     BOOST_CONTRACT_DETAIL_DECLINLINE
0163     failure_handler get_check_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
0164         boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
0165         return get_check_failure_unlocked();
0166     }
0167 
0168     BOOST_CONTRACT_DETAIL_DECLINLINE
0169     void check_failure_unlocked() /* can throw */ {
0170         check_failure_handler::ref()();
0171     }
0172     
0173     BOOST_CONTRACT_DETAIL_DECLINLINE
0174     void check_failure_locked() /* can throw */ {
0175         boost::lock_guard<boost::mutex> lock(check_failure_mutex::ref());
0176         check_failure_unlocked();
0177     }
0178     
0179     // Precondition failure.
0180 
0181     struct pre_failure_mutex_tag;
0182     typedef boost::contract::detail::static_local_var<pre_failure_mutex_tag,
0183             boost::mutex> pre_failure_mutex;
0184 
0185     struct pre_failure_handler_tag;
0186     typedef boost::contract::detail::static_local_var_init<
0187         pre_failure_handler_tag,
0188         from_failure_handler,
0189         void (*)(from),
0190         &default_from_handler<pre_failure_key>
0191     > pre_failure_handler;
0192 
0193     BOOST_CONTRACT_DETAIL_DECLINLINE
0194     from_failure_handler const& set_pre_failure_unlocked(from_failure_handler
0195             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0196         pre_failure_handler::ref() = f;
0197         return f;
0198     }
0199     
0200     BOOST_CONTRACT_DETAIL_DECLINLINE
0201     from_failure_handler const& set_pre_failure_locked(from_failure_handler
0202             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0203         boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
0204         return set_pre_failure_unlocked(f);
0205     }
0206 
0207     BOOST_CONTRACT_DETAIL_DECLINLINE
0208     from_failure_handler get_pre_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
0209         return pre_failure_handler::ref();
0210     }
0211 
0212     BOOST_CONTRACT_DETAIL_DECLINLINE
0213     from_failure_handler get_pre_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
0214         boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
0215         return get_pre_failure_unlocked();
0216     }
0217 
0218     BOOST_CONTRACT_DETAIL_DECLINLINE
0219     void pre_failure_unlocked(from where) /* can throw */ {
0220         pre_failure_handler::ref()(where);
0221     }
0222     
0223     BOOST_CONTRACT_DETAIL_DECLINLINE
0224     void pre_failure_locked(from where) /* can throw */ {
0225         boost::lock_guard<boost::mutex> lock(pre_failure_mutex::ref());
0226         pre_failure_unlocked(where);
0227     }
0228     
0229     // Postcondition failure.
0230 
0231     struct post_failure_mutex_tag;
0232     typedef boost::contract::detail::static_local_var<post_failure_mutex_tag,
0233             boost::mutex> post_failure_mutex;
0234 
0235     struct post_failure_handler_tag;
0236     typedef boost::contract::detail::static_local_var_init<
0237         post_failure_handler_tag,
0238         from_failure_handler,
0239         void (*)(from),
0240         &default_from_handler<post_failure_key>
0241     > post_failure_handler;
0242 
0243     BOOST_CONTRACT_DETAIL_DECLINLINE
0244     from_failure_handler const& set_post_failure_unlocked(from_failure_handler
0245             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0246         post_failure_handler::ref() = f;
0247         return f;
0248     }
0249     
0250     BOOST_CONTRACT_DETAIL_DECLINLINE
0251     from_failure_handler const& set_post_failure_locked(from_failure_handler
0252             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0253         boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
0254         return set_post_failure_unlocked(f);
0255     }
0256 
0257     BOOST_CONTRACT_DETAIL_DECLINLINE
0258     from_failure_handler get_post_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
0259         return post_failure_handler::ref();
0260     }
0261 
0262     BOOST_CONTRACT_DETAIL_DECLINLINE
0263     from_failure_handler get_post_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
0264         boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
0265         return get_post_failure_unlocked();
0266     }
0267 
0268     BOOST_CONTRACT_DETAIL_DECLINLINE
0269     void post_failure_unlocked(from where) /* can throw */ {
0270         post_failure_handler::ref()(where);
0271     }
0272     
0273     BOOST_CONTRACT_DETAIL_DECLINLINE
0274     void post_failure_locked(from where) /* can throw */ {
0275         boost::lock_guard<boost::mutex> lock(post_failure_mutex::ref());
0276         post_failure_unlocked(where);
0277     }
0278     
0279     // Except failure.
0280 
0281     struct except_failure_mutex_tag;
0282     typedef boost::contract::detail::static_local_var<except_failure_mutex_tag,
0283             boost::mutex> except_failure_mutex;
0284 
0285     struct except_failure_handler_tag;
0286     typedef boost::contract::detail::static_local_var_init<
0287         except_failure_handler_tag,
0288         from_failure_handler,
0289         void (*)(from),
0290         &default_from_handler<except_failure_key>
0291     > except_failure_handler;
0292 
0293     BOOST_CONTRACT_DETAIL_DECLINLINE
0294     from_failure_handler const& set_except_failure_unlocked(from_failure_handler
0295             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0296         except_failure_handler::ref() = f;
0297         return f;
0298     }
0299     
0300     BOOST_CONTRACT_DETAIL_DECLINLINE
0301     from_failure_handler const& set_except_failure_locked(from_failure_handler
0302             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0303         boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
0304         return set_except_failure_unlocked(f);
0305     }
0306 
0307     BOOST_CONTRACT_DETAIL_DECLINLINE
0308     from_failure_handler get_except_failure_unlocked()
0309             BOOST_NOEXCEPT_OR_NOTHROW {
0310         return except_failure_handler::ref();
0311     }
0312 
0313     BOOST_CONTRACT_DETAIL_DECLINLINE
0314     from_failure_handler get_except_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
0315         boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
0316         return get_except_failure_unlocked();
0317     }
0318 
0319     BOOST_CONTRACT_DETAIL_DECLINLINE
0320     void except_failure_unlocked(from where) /* can throw */ {
0321         except_failure_handler::ref()(where);
0322     }
0323     
0324     BOOST_CONTRACT_DETAIL_DECLINLINE
0325     void except_failure_locked(from where) /* can throw */ {
0326         boost::lock_guard<boost::mutex> lock(except_failure_mutex::ref());
0327         except_failure_unlocked(where);
0328     }
0329 
0330     // Old-copy failure.
0331 
0332     struct old_failure_mutex_tag;
0333     typedef boost::contract::detail::static_local_var<old_failure_mutex_tag,
0334             boost::mutex> old_failure_mutex;
0335 
0336     struct old_failure_handler_tag;
0337     typedef boost::contract::detail::static_local_var_init<
0338         old_failure_handler_tag,
0339         from_failure_handler,
0340         void (*)(from),
0341         &default_from_handler<old_failure_key>
0342     > old_failure_handler;
0343 
0344     BOOST_CONTRACT_DETAIL_DECLINLINE
0345     from_failure_handler const& set_old_failure_unlocked(from_failure_handler
0346             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0347         old_failure_handler::ref() = f;
0348         return f;
0349     }
0350     
0351     BOOST_CONTRACT_DETAIL_DECLINLINE
0352     from_failure_handler const& set_old_failure_locked(from_failure_handler
0353             const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0354         boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
0355         return set_old_failure_unlocked(f);
0356     }
0357 
0358     BOOST_CONTRACT_DETAIL_DECLINLINE
0359     from_failure_handler get_old_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW {
0360         return old_failure_handler::ref();
0361     }
0362 
0363     BOOST_CONTRACT_DETAIL_DECLINLINE
0364     from_failure_handler get_old_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW {
0365         boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
0366         return get_old_failure_unlocked();
0367     }
0368 
0369     BOOST_CONTRACT_DETAIL_DECLINLINE
0370     void old_failure_unlocked(from where) /* can throw */ {
0371         old_failure_handler::ref()(where);
0372     }
0373     
0374     BOOST_CONTRACT_DETAIL_DECLINLINE
0375     void old_failure_locked(from where) /* can throw */ {
0376         boost::lock_guard<boost::mutex> lock(old_failure_mutex::ref());
0377         old_failure_unlocked(where);
0378     }
0379     
0380     // Entry invariant failure.
0381 
0382     struct entry_inv_failure_mutex_tag;
0383     typedef boost::contract::detail::static_local_var<
0384             entry_inv_failure_mutex_tag, boost::mutex> entry_inv_failure_mutex;
0385 
0386     struct entry_inv_failure_handler_tag;
0387     typedef boost::contract::detail::static_local_var_init<
0388         entry_inv_failure_handler_tag,
0389         from_failure_handler,
0390         void (*)(from),
0391         &default_from_handler<entry_inv_failure_key>
0392     > entry_inv_failure_handler;
0393 
0394     BOOST_CONTRACT_DETAIL_DECLINLINE
0395     from_failure_handler const& set_entry_inv_failure_unlocked(
0396             from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0397         entry_inv_failure_handler::ref() = f;
0398         return f;
0399     }
0400     
0401     BOOST_CONTRACT_DETAIL_DECLINLINE
0402     from_failure_handler const& set_entry_inv_failure_locked(
0403             from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0404         boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
0405         return set_entry_inv_failure_unlocked(f);
0406     }
0407 
0408     BOOST_CONTRACT_DETAIL_DECLINLINE
0409     from_failure_handler get_entry_inv_failure_unlocked()
0410             BOOST_NOEXCEPT_OR_NOTHROW {
0411         return entry_inv_failure_handler::ref();
0412     }
0413 
0414     BOOST_CONTRACT_DETAIL_DECLINLINE
0415     from_failure_handler get_entry_inv_failure_locked()
0416             BOOST_NOEXCEPT_OR_NOTHROW {
0417         boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
0418         return get_entry_inv_failure_unlocked();
0419     }
0420 
0421     BOOST_CONTRACT_DETAIL_DECLINLINE
0422     void entry_inv_failure_unlocked(from where) /* can throw */ {
0423         entry_inv_failure_handler::ref()(where);
0424     }
0425     
0426     BOOST_CONTRACT_DETAIL_DECLINLINE
0427     void entry_inv_failure_locked(from where) /* can throw */ {
0428         boost::lock_guard<boost::mutex> lock(entry_inv_failure_mutex::ref());
0429         entry_inv_failure_unlocked(where);
0430     }
0431     
0432     // Exit invariant failure.
0433 
0434     struct exit_inv_failure_mutex_tag;
0435     typedef boost::contract::detail::static_local_var<
0436             exit_inv_failure_mutex_tag, boost::mutex> exit_inv_failure_mutex;
0437 
0438     struct exit_inv_failure_handler_tag;
0439     typedef boost::contract::detail::static_local_var_init<
0440         exit_inv_failure_handler_tag,
0441         from_failure_handler,
0442         void (*)(from),
0443         &default_from_handler<exit_inv_failure_key>
0444     > exit_inv_failure_handler;
0445 
0446     BOOST_CONTRACT_DETAIL_DECLINLINE
0447     from_failure_handler const& set_exit_inv_failure_unlocked(
0448             from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0449         exit_inv_failure_handler::ref() = f;
0450         return f;
0451     }
0452     
0453     BOOST_CONTRACT_DETAIL_DECLINLINE
0454     from_failure_handler const& set_exit_inv_failure_locked(
0455             from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
0456         boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
0457         return set_exit_inv_failure_unlocked(f);
0458     }
0459 
0460     BOOST_CONTRACT_DETAIL_DECLINLINE
0461     from_failure_handler get_exit_inv_failure_unlocked()
0462             BOOST_NOEXCEPT_OR_NOTHROW {
0463         return exit_inv_failure_handler::ref();
0464     }
0465 
0466     BOOST_CONTRACT_DETAIL_DECLINLINE
0467     from_failure_handler get_exit_inv_failure_locked()
0468             BOOST_NOEXCEPT_OR_NOTHROW {
0469         boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
0470         return get_exit_inv_failure_unlocked();
0471     }
0472 
0473     BOOST_CONTRACT_DETAIL_DECLINLINE
0474     void exit_inv_failure_unlocked(from where) /* can throw */ {
0475         exit_inv_failure_handler::ref()(where);
0476     }
0477     
0478     BOOST_CONTRACT_DETAIL_DECLINLINE
0479     void exit_inv_failure_locked(from where) /* can throw */ {
0480         boost::lock_guard<boost::mutex> lock(exit_inv_failure_mutex::ref());
0481         exit_inv_failure_unlocked(where);
0482     }
0483 }
0484 
0485 from_failure_handler const& set_entry_invariant_failure(
0486         from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
0487 
0488 from_failure_handler const& set_exit_invariant_failure(
0489         from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
0490 
0491 BOOST_CONTRACT_DETAIL_DECLINLINE
0492 from_failure_handler const& set_invariant_failure(
0493         from_failure_handler const& f)  BOOST_NOEXCEPT_OR_NOTHROW {
0494     set_entry_invariant_failure(f);
0495     set_exit_invariant_failure(f);
0496     return f;
0497 }
0498 
0499 } } // namespace
0500 
0501 #endif // #include guard
0502