diff --git a/Jamroot b/Jamroot
index 507c69f..5501054 100644
--- a/Jamroot
+++ b/Jamroot
@@ -1,12 +1,13 @@
import testing ;
import os ;
+import feature ;
if ! [ os.environ BOOST_ROOT ] {
- exit "error: set BOOST_ROOT environment variable to Boost root directory" ;
+ exit "Error: set BOOST_ROOT environment variable to Boost root directory" ;
}
local BOOST_ROOT = [ os.environ BOOST_ROOT ] ;
-echo "using: Boost libraries from \"$(BOOST_ROOT)\" (see $BOOST_ROOT)" ;
+echo "Using Boost libraries from \"$(BOOST_ROOT)\" (see $BOOST_ROOT)" ;
use-project boost : $(BOOST_ROOT) ;
project
@@ -20,15 +21,28 @@ project
;
rule subdir-usage ( ) {
- echo ;
- echo "usage: [time] bjam [-aq toolset=msvc,gcc,clang] DIR_NAME[-FILE_NAME[-no_...]] [--clean] [; echo $?]" ;
- echo "where: -no_... = -no[_entryinv][_pre][_exitinv][_post] | -no_all | n/a" ;
- echo ;
+ echo "
+Usage: [time] bjam [-aq] [OPTION]... DIR[-CPP_FILE_NAME] [--clean] [; echo $?]
+Build and run Boost.Contract tests and examples.
+
+Options:
+ toolset=msvc,gcc,clang use different compilers
+ boost_contract-link=shared,static, compile Boost.Contract lib as shared,
+ header static, or header-only
+ boost_contract-no=all_on,entryinv, selectively turn off contract checking
+ pre,exitinv,post,
+ entryinv_pre,entryinv_exitinv,entryinv_post,pre_exitinv,
+ pre_post,exitinv_post,pre_exitinv_post,
+ entryinv_exitinv_post,entryinv_pre_post,
+ entryinv_pre_exitinv,entryinv_pre_exitinv_post
+" ;
}
rule subdir-compile-fail ( subdir : cpp_fname : requirements * ) {
compile-fail $(subdir)/$(cpp_fname).cpp
:
+ shared:../build//boost_contract
+ static:../build//boost_contract
$(subdir)
$(requirements)
:
@@ -39,6 +53,8 @@ rule subdir-compile-fail ( subdir : cpp_fname : requirements * ) {
rule subdir-run ( subdir : cpp_fname : requirements * ) {
run $(subdir)/$(cpp_fname).cpp : :
:
+ shared:../build//boost_contract
+ static:../build//boost_contract
$(subdir)
$(requirements)
:
@@ -46,170 +62,110 @@ rule subdir-run ( subdir : cpp_fname : requirements * ) {
;
}
-rule subdir-run-withno ( subdir : cpp_fname : requirements * ) {
- subdir-run $(subdir) : $(cpp_fname) : $(requirements) ;
- # Compilation of 1 contract off.
- run $(subdir)/$(cpp_fname).cpp : :
+rule subdir-lib ( subdir : cpp_fname : requirements * ) {
+ lib $(subdir)-$(cpp_fname) : $(subdir)/$(cpp_fname).cpp
:
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- $(subdir)
+ shared:../build//boost_contract
+ static:../build//boost_contract
$(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_pre
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_exitinv
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_post
- ;
- # Compilation of 2 contracts off.
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_pre
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_exitinv
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_post
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_pre_exitinv
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_pre_post
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_exitinv_post
- ;
- # Compilation of 3 contracts off.
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_pre_exitinv_post
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_exitinv_post
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_pre_post
- ;
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_pre_exitinv
- ;
- # Compilation of all 4 contracts off.
- run $(subdir)/$(cpp_fname).cpp : :
- :
- BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
- BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
- BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
- $(subdir)
- $(requirements)
- :
- $(subdir)-$(cpp_fname)-no_entryinv_pre_exitinv_post
- ;
- # Group all compilation off targets.
- test-suite $(subdir)-$(cpp_fname)-no_all
- :
- $(subdir)-$(cpp_fname)-no_entryinv
- $(subdir)-$(cpp_fname)-no_pre
- $(subdir)-$(cpp_fname)-no_exitinv
- $(subdir)-$(cpp_fname)-no_post
-
- $(subdir)-$(cpp_fname)-no_entryinv_pre
- $(subdir)-$(cpp_fname)-no_entryinv_exitinv
- $(subdir)-$(cpp_fname)-no_entryinv_post
- $(subdir)-$(cpp_fname)-no_pre_exitinv
- $(subdir)-$(cpp_fname)-no_pre_post
- $(subdir)-$(cpp_fname)-no_exitinv_post
-
- $(subdir)-$(cpp_fname)-no_pre_exitinv_post
- $(subdir)-$(cpp_fname)-no_entryinv_exitinv_post
- $(subdir)-$(cpp_fname)-no_entryinv_pre_post
- $(subdir)-$(cpp_fname)-no_entryinv_pre_exitinv
-
- $(subdir)-$(cpp_fname)-no_entryinv_pre_exitinv_post
;
}
+feature.feature boost_contract-link : shared static header :
+ composite propagated link-incompatible ;
+feature.compose shared : shared ;
+feature.compose static : static ;
+feature.compose header :
+ BOOST_CONTRACT_HEADER_ONLY ;
+
+feature.feature boost_contract-no
+:
+ all_on entryinv pre exitinv post entryinv_pre entryinv_exitinv
+ entryinv_post pre_exitinv pre_post exitinv_post pre_exitinv_post
+ entryinv_exitinv_post entryinv_pre_post entryinv_pre_exitinv
+ entryinv_pre_exitinv_post
+:
+ composite propagated link-incompatible
+;
+# 1 contract off.
+feature.compose entryinv
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+;
+feature.compose pre
+:
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+;
+feature.compose exitinv
+:
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+;
+feature.compose post
+:
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+# 2 contracts off.
+feature.compose entryinv_pre
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+;
+feature.compose entryinv_exitinv
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+;
+feature.compose entryinv_post
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+feature.compose pre_exitinv
+:
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+;
+feature.compose pre_post
+:
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+feature.compose exitinv_post
+:
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+# 3 contracts off.
+feature.compose pre_exitinv_post
+:
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+feature.compose entryinv_exitinv_post
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+feature.compose entryinv_pre_post
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+feature.compose entryinv_pre_exitinv
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+;
+# All 4 contracts oof.
+feature.compose entryinv_pre_exitinv_post
+:
+ BOOST_CONTRACT_CONFIG_NO_ENTRY_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_PRECONDITIONS
+ BOOST_CONTRACT_CONFIG_NO_EXIT_INVARIANTS
+ BOOST_CONTRACT_CONFIG_NO_POSTCONDITIONS
+;
+
diff --git a/build/Jamfile.v2 b/build/Jamfile.v2
new file mode 100644
index 0000000..6ed2188
--- /dev/null
+++ b/build/Jamfile.v2
@@ -0,0 +1,4 @@
+
+lib boost_contract : ../src/contract.cpp :
+ shared:BOOST_CONTRACT_DYN_LINK ;
+
diff --git a/include/boost/contract/aux_/check_guard.hpp b/include/boost/contract/aux_/check_guard.hpp
index f02a4b0..3c90a41 100644
--- a/include/boost/contract/aux_/check_guard.hpp
+++ b/include/boost/contract/aux_/check_guard.hpp
@@ -3,6 +3,7 @@
#define BOOST_CONTRACT_AUX_CHECK_GUARD_HPP_
/** @cond */
+#include
#include
/** @endcond */
@@ -10,23 +11,26 @@ namespace boost { namespace contract { namespace aux {
// TODO: Consider what to do with multi-threads... shall I use multi-reads/one-write locks via boost::shared_mutex? should each thread have its own contract checking bool resource? If global locks must be introduced, provide a NO_TREAD_SAFE configuration macro to disable them.
-class check_guard :
+class BOOST_CONTRACT_AUX_DECL check_guard :
private boost::noncopyable // Non-copyable resource (might use mutex, etc.).
{
public:
- explicit check_guard() { checking_ = true; }
- ~check_guard() { checking_ = false; }
+ explicit check_guard();
+ ~check_guard();
- static bool checking() { return checking_; }
+ static bool checking();
private:
static bool checking_;
};
// TODO: This and all other lib states (failure handler functors from exception.hpp, etc.) must go into a .cpp with dyn linking (DLL). Also move as much as code as possible to .cpp files (and try to minimize template is not strictly necessary) so to speed up compilation.
-bool check_guard::checking_ = false;
} } } // namespace
+#if BOOST_CONTRACT_HEADER_ONLY
+ #include
+#endif
+
#endif // #include guard
diff --git a/include/boost/contract/aux_/decl.hpp b/include/boost/contract/aux_/decl.hpp
index 093c7a1..942d1b4 100644
--- a/include/boost/contract/aux_/decl.hpp
+++ b/include/boost/contract/aux_/decl.hpp
@@ -11,9 +11,23 @@
#include
#include
#endif
+#include
/* PUBLIC */
+// IMPORTANT: In general, this library should always and only be compiled and
+// used as a shared library. Otherwise, lib's state won't be shared among
+// different user programs and user libraries.
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTRACT_DYN_LINK)
+ #ifdef BOOST_CONTRACT_AUX_CONFIG_SOURCE
+ #define BOOST_CONTRACT_AUX_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_CONTRACT_AUX_DECL BOOST_SYMBOL_IMPORT
+ #endif
+#else
+ #define BOOST_CONTRACT_AUX_DECL /* nothing */
+#endif
+
#define BOOST_CONTRACT_AUX_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
arity, is_friend, has_result, \
O, R, F, C, Args, \
diff --git a/include/boost/contract/aux_/inlined/aux_/check_guard.hpp b/include/boost/contract/aux_/inlined/aux_/check_guard.hpp
new file mode 100644
index 0000000..25ba2b8
--- /dev/null
+++ b/include/boost/contract/aux_/inlined/aux_/check_guard.hpp
@@ -0,0 +1,20 @@
+
+#ifndef BOOST_CONTRACT_AUX_INLINED_AUX_CHECK_GUARD_HPP_
+#define BOOST_CONTRACT_AUX_INLINED_AUX_CHECK_GUARD_HPP_
+
+#include
+
+namespace boost { namespace contract { namespace aux {
+
+check_guard::check_guard() { checking_ = true; }
+
+check_guard::~check_guard() { checking_ = false; }
+
+bool check_guard::checking() { return checking_; }
+
+bool check_guard::checking_ = false;
+
+} } } // namespace
+
+#endif
+
diff --git a/include/boost/contract/aux_/inlined/core/exception.hpp b/include/boost/contract/aux_/inlined/core/exception.hpp
new file mode 100644
index 0000000..a3a334b
--- /dev/null
+++ b/include/boost/contract/aux_/inlined/core/exception.hpp
@@ -0,0 +1,219 @@
+
+#ifndef BOOST_CONTRACT_AUX_INLINED_EXCEPTION_HPP_
+#define BOOST_CONTRACT_AUX_INLINED_EXCEPTION_HPP_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* PRIVATE */
+
+// TODO: Re-enable these mutexes for failure handlers.
+#define BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex) \
+ /*boost::mutex::scoped_lock lock(_mutex);*/
+
+#define BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(_mutex, handler, f) \
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
+ assertion_failure_handler result = handler; \
+ handler = f; \
+ return result;
+
+#define BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(_mutex, handler) \
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
+ return handler;
+
+#define BOOST_CONTRACT_EXCEPTION_HANDLER_(_mutex, handler, where) \
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
+ handler(where);
+
+/* CODE */
+
+namespace boost { namespace contract {
+
+exception::~exception() {}
+
+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();
+}
+
+bad_virtual_result_cast::~bad_virtual_result_cast() {}
+
+char const* bad_virtual_result_cast::what() const BOOST_NOEXCEPT {
+ return what_.c_str();
+}
+
+assertion_failure::assertion_failure(char const* const file,
+ unsigned long const line, char const* const code) :
+ file_(file), line_(line), code_(code)
+{ init(); }
+
+assertion_failure::assertion_failure(char const* const code) :
+ file_(""), line_(0), code_(code)
+{ init(); }
+
+assertion_failure::~assertion_failure() {}
+
+char const* assertion_failure::what() const BOOST_NOEXCEPT {
+ return what_.c_str();
+}
+
+char const* const assertion_failure::file() const { return file_; }
+
+unsigned long assertion_failure::line() const { return line_; }
+
+char const* const assertion_failure::code() const { return code_; }
+
+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 { pre_key, post_key, entry_inv_key, exit_inv_key };
+
+ template
+ void default_handler(from) {
+ std::string k = "";
+ switch(Key) {
+ case pre_key: k = "precondition "; break;
+ case post_key: k = "postcondition "; break;
+ case entry_inv_key: k = "entry invariant "; break;
+ case exit_inv_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(...) {
+ std::cerr << k << "checking threw following exception:" << std::endl
+ << boost::current_exception_diagnostic_information();
+ }
+ std::terminate(); // Default handlers log and call terminate.
+ }
+
+ // TODO: These (and all other globals) need extern, etc.
+
+ //boost::mutex pre_failure_mutex;
+ BOOST_CONTRACT_AUX_DECL assertion_failure_handler
+ pre_failure_handler = &default_handler;
+
+ //boost::mutex post_failure_mutex;
+ BOOST_CONTRACT_AUX_DECL assertion_failure_handler
+ post_failure_handler = &default_handler;
+
+ //boost::mutex entry_inv_failure_mutex;
+ BOOST_CONTRACT_AUX_DECL assertion_failure_handler
+ entry_inv_failure_handler = &default_handler;
+
+ //boost::mutex exit_inv_failure_mutex;
+ BOOST_CONTRACT_AUX_DECL assertion_failure_handler
+ exit_inv_failure_handler = &default_handler;
+}
+
+// Contract compilation on/off cannot change following set/get impl.
+
+assertion_failure_handler set_precondition_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::pre_failure_mutex,
+ exception_::pre_failure_handler, f);
+}
+
+assertion_failure_handler get_precondition_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::pre_failure_mutex,
+ exception_::pre_failure_handler);
+}
+
+void precondition_failure(from where) /* can throw */ {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::pre_failure_mutex,
+ exception_::pre_failure_handler, where)
+}
+
+assertion_failure_handler set_postcondition_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::post_failure_mutex,
+ exception_::post_failure_handler, f);
+}
+
+assertion_failure_handler get_postcondition_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::post_failure_mutex,
+ exception_::post_failure_handler);
+}
+
+void postcondition_failure(from where) /* can throw */ {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::post_failure_mutex,
+ exception_::post_failure_handler, where);
+}
+
+assertion_failure_handler set_entry_invariant_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::entry_inv_failure_mutex,
+ exception_::entry_inv_failure_handler, f);
+}
+
+assertion_failure_handler get_entry_invariant_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::entry_inv_failure_mutex,
+ exception_::entry_inv_failure_handler);
+}
+
+void entry_invariant_failure(from where) /* can throw */ {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::entry_inv_failure_mutex,
+ exception_::entry_inv_failure_handler, where);
+}
+
+assertion_failure_handler set_exit_invariant_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::exit_inv_failure_mutex,
+ exception_::exit_inv_failure_handler, f);
+}
+
+assertion_failure_handler get_exit_invariant_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::exit_inv_failure_mutex,
+ exception_::exit_inv_failure_handler);
+}
+
+void exit_invariant_failure(from where) /* can throw */ {
+ BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::exit_inv_failure_mutex,
+ exception_::exit_inv_failure_handler, where);
+}
+
+void set_invariant_failure(assertion_failure_handler const& f)
+ BOOST_NOEXCEPT_OR_NOTHROW {
+ set_entry_invariant_failure(f);
+ set_exit_invariant_failure(f);
+}
+
+void set_failure(assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
+ set_precondition_failure(f);
+ set_postcondition_failure(f);
+ set_invariant_failure(f);
+}
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/include/boost/contract/core/config.hpp b/include/boost/contract/core/config.hpp
index 8d79872..3952151 100644
--- a/include/boost/contract/core/config.hpp
+++ b/include/boost/contract/core/config.hpp
@@ -4,12 +4,19 @@
/** @file */
-// IMPORTANT: This header MUST NOT #include any other header. That way users
-// can #include this header and not #include any of this lib headers after that
-// depending on the contract 0/1 macros below ensuring no compilation overhead.
+// IMPORTANT: This header MUST NOT #include any other header of this lib.
+// That way users can #include this header and not #include any of this lib
+// headers after that depending on the contract 0/1 macros below ensuring no
+// compilation overhead.
// TODO: Can I compile lib1 with some contract on/off, lib2 with other contracts on/off and then link the two together?
+// TODO: To be consistent... should I use CONFIG only for staff below that has a default #define, but for PREMISSIVE, etc. do not use CONFIG?
+// BOOST_CONTRACT_DYN_LINK
+// BOOST_CONTRACT_HEADER_ONLY
+
+// BOOST_CONTRACT_THREAD_DISABLE
+
#ifndef BOOST_CONTRACT_CONFIG_MAX_ARGS
# define BOOST_CONTRACT_CONFIG_MAX_ARGS 10
#endif
diff --git a/include/boost/contract/core/exception.hpp b/include/boost/contract/core/exception.hpp
index 6aa3025..037ddeb 100644
--- a/include/boost/contract/core/exception.hpp
+++ b/include/boost/contract/core/exception.hpp
@@ -4,16 +4,11 @@
/** @file */
-#include
-/** @cond */
+#include
#include
-#include
#include
#include
-#include
#include
-#include
-/** @endcond */
// NOTE: This code should not change (not even its impl) based on the
// CONFIG_NO_... macros. For example, preconditions_failure() should still call
@@ -21,88 +16,49 @@
// #defined, because user code might explicitly call precondition_failure() (for
// whatever reason...). Otherwise, the public API of this lib will change.
-/* PRIVATE */
-
-#define BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex) \
- /*boost::mutex::scoped_lock lock(_mutex);*/
-
-#define BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(_mutex, handler, f) \
- BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
- assertion_failure_handler result = handler; \
- handler = f; \
- return result;
-
-#define BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(_mutex, handler) \
- BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
- return handler;
-
-#define BOOST_CONTRACT_EXCEPTION_HANDLER_(_mutex, handler, where) \
- BOOST_CONTRACT_EXCEPTION_HANDLER_SCOPED_LOCK_(_mutex); \
- handler(where);
-
-/* CODE */
-
namespace boost { namespace contract {
// Placeholder base class to group all this lib exceptions.
// IMPORTANT: Must not inherit from std::exception as derived exceptions will.
-class exception {};
+class BOOST_CONTRACT_AUX_DECL exception {
+public:
+ virtual ~exception();
+};
// Rationale: boost::bad_any_cast exception does not print from/to type names,
// so throw custom exception.
-class bad_virtual_result_cast : // Copyable (as string, etc.).
+// Copyable (as string, etc.).
+class BOOST_CONTRACT_AUX_DECL bad_virtual_result_cast :
public std::bad_cast, public boost::contract::exception {
public:
explicit 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();
- }
+ char const* to_type_name);
+ virtual ~bad_virtual_result_cast();
- virtual char const* what() const BOOST_NOEXCEPT { return what_.c_str(); }
+ virtual char const* what() const BOOST_NOEXCEPT;
private:
std::string what_;
};
-class assertion_failure : // Copyable (as string, etc.).
+// Copyable (as string, etc.).
+class BOOST_CONTRACT_AUX_DECL assertion_failure :
public std::exception, public boost::contract::exception {
public:
explicit assertion_failure(char const* const file = "",
- unsigned long const line = 0, char const* const code = "") :
- file_(file), line_(line), code_(code)
- { init(); }
-
- explicit assertion_failure(char const* const code) :
- file_(""), line_(0), code_(code)
- { init(); }
+ unsigned long const line = 0, char const* const code = "");
+ explicit assertion_failure(char const* const code);
+ virtual ~assertion_failure();
- virtual ~assertion_failure() {}
+ // Return something like `assertion "..." failed: file "...", line ...`.
+ virtual char const* what() const BOOST_NOEXCEPT;
- // Return `assertion "..." failed: file "...", line ...`.
- virtual char const* what() const BOOST_NOEXCEPT { return what_.c_str(); }
-
- char const* const file() const { return file_; }
- unsigned long line() const { return line_; }
- char const* const code() const { return code_; }
+ char const* const file() const;
+ unsigned long line() const;
+ char const* const code() const;
private:
- void 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();
- }
+ void init();
char const* const file_;
unsigned long const line_;
@@ -110,134 +66,57 @@ private:
std::string what_;
};
-enum from {
- from_constructor,
- from_destructor,
- from_function
-};
+enum from { from_constructor, from_destructor, from_function };
// Use Boost.Function to handle also lambdas, binds, etc,
typedef boost::function assertion_failure_handler;
-namespace exception_ {
- enum failure_key { pre_key, post_key, entry_inv_key, exit_inv_key };
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL set_precondition_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
- template
- void default_handler(from) {
- std::string k = "";
- switch(Key) {
- case pre_key: k = "precondition "; break;
- case post_key: k = "postcondition "; break;
- case entry_inv_key: k = "entry invariant "; break;
- case exit_inv_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(...) {
- std::cerr << k << "checking threw following exception:" << std::endl
- << boost::current_exception_diagnostic_information();
- }
- std::terminate(); // Default handlers log and call terminate.
- }
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL get_precondition_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW;
- //boost::mutex pre_failure_mutex;
- assertion_failure_handler pre_failure_handler =
- &default_handler;
-
- //boost::mutex post_failure_mutex;
- assertion_failure_handler post_failure_handler =
- &default_handler;
-
- //boost::mutex entry_inv_failure_mutex;
- assertion_failure_handler entry_inv_failure_handler =
- &default_handler;
-
- //boost::mutex exit_inv_failure_mutex;
- assertion_failure_handler exit_inv_failure_handler =
- &default_handler;
-}
+void BOOST_CONTRACT_AUX_DECL precondition_failure(from where) /* can throw */;
-// Contract compilation on/off cannot change following set/get.
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL set_postcondition_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler set_precondition_failure(
- assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::pre_failure_mutex,
- exception_::pre_failure_handler, f);
-}
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL get_postcondition_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler get_precondition_failure()
- BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::pre_failure_mutex,
- exception_::pre_failure_handler);
-}
+void BOOST_CONTRACT_AUX_DECL postcondition_failure(from where) /* can throw */;
-void precondition_failure(from where) /* can throw */ {
- BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::pre_failure_mutex,
- exception_::pre_failure_handler, where)
-}
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL set_entry_invariant_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler set_postcondition_failure(
- assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::post_failure_mutex,
- exception_::post_failure_handler, f);
-}
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL get_entry_invariant_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler get_postcondition_failure()
- BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::post_failure_mutex,
- exception_::post_failure_handler);
-}
+void BOOST_CONTRACT_AUX_DECL entry_invariant_failure(from where)
+ /* can throw */;
-void postcondition_failure(from where) /* can throw */ {
- BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::post_failure_mutex,
- exception_::post_failure_handler, where);
-}
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL set_exit_invariant_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler set_entry_invariant_failure(
- assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::entry_inv_failure_mutex,
- exception_::entry_inv_failure_handler, f);
-}
+assertion_failure_handler BOOST_CONTRACT_AUX_DECL get_exit_invariant_failure()
+ BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler get_entry_invariant_failure()
- BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::entry_inv_failure_mutex,
- exception_::entry_inv_failure_handler);
-}
+void BOOST_CONTRACT_AUX_DECL exit_invariant_failure(from where) /* can throw */;
-void entry_invariant_failure(from where) /* can throw */ {
- BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::entry_inv_failure_mutex,
- exception_::entry_inv_failure_handler, where);
-}
+// Set all inv failures (entry inv and exit inv) at once.
+void BOOST_CONTRACT_AUX_DECL set_invariant_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
-assertion_failure_handler set_exit_invariant_failure(
- assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_SET_(exception_::exit_inv_failure_mutex,
- exception_::exit_inv_failure_handler, f);
-}
-
-assertion_failure_handler get_exit_invariant_failure()
- BOOST_NOEXCEPT_OR_NOTHROW {
- BOOST_CONTRACT_EXCEPTION_HANDLER_GET_(exception_::exit_inv_failure_mutex,
- exception_::exit_inv_failure_handler);
-}
-
-void exit_invariant_failure(from where) /* can throw */ {
- BOOST_CONTRACT_EXCEPTION_HANDLER_(exception_::exit_inv_failure_mutex,
- exception_::exit_inv_failure_handler, where);
-}
-
-void set_invariant_failure(assertion_failure_handler const& f)
- BOOST_NOEXCEPT_OR_NOTHROW {
- set_entry_invariant_failure(f);
- set_exit_invariant_failure(f);
-}
+// Set all failures (pre, post, entry inv, and exit int) at once.
+void BOOST_CONTRACT_AUX_DECL set_failure(
+ assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
} } // namespace
+#if BOOST_CONTRACT_HEADER_ONLY
+ #include
+#endif
+
#endif // #include guard
diff --git a/src/contract.cpp b/src/contract.cpp
new file mode 100644
index 0000000..ddcf928
--- /dev/null
+++ b/src/contract.cpp
@@ -0,0 +1,5 @@
+
+#define BOOST_CONTRACT_AUX_CONFIG_SOURCE
+#include
+#include
+
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 4ddee82..b0b887a 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -3,39 +3,39 @@ subdir-usage ;
test-suite constructor
:
- [ subdir-run-withno constructor : decl_pre_all ]
- [ subdir-run-withno constructor : decl_pre_ends ]
- [ subdir-run-withno constructor : decl_pre_mid ]
- [ subdir-run-withno constructor : decl_pre_none ]
+ [ subdir-run constructor : decl_pre_all ]
+ [ subdir-run constructor : decl_pre_ends ]
+ [ subdir-run constructor : decl_pre_mid ]
+ [ subdir-run constructor : decl_pre_none ]
- [ subdir-run-withno constructor : decl_post_all ]
- [ subdir-run-withno constructor : decl_post_ends ]
- [ subdir-run-withno constructor : decl_post_mid ]
- [ subdir-run-withno constructor : decl_post_none ]
+ [ subdir-run constructor : decl_post_all ]
+ [ subdir-run constructor : decl_post_ends ]
+ [ subdir-run constructor : decl_post_mid ]
+ [ subdir-run constructor : decl_post_none ]
- [ subdir-run-withno constructor : decl_entry_static_inv_all ]
- [ subdir-run-withno constructor : decl_entry_static_inv_ends ]
- [ subdir-run-withno constructor : decl_entry_static_inv_mid ]
- [ subdir-run-withno constructor : decl_entry_static_inv_none ]
+ [ subdir-run constructor : decl_entry_static_inv_all ]
+ [ subdir-run constructor : decl_entry_static_inv_ends ]
+ [ subdir-run constructor : decl_entry_static_inv_mid ]
+ [ subdir-run constructor : decl_entry_static_inv_none ]
- [ subdir-run-withno constructor : decl_exit_static_inv_all ]
- [ subdir-run-withno constructor : decl_exit_static_inv_ends ]
- [ subdir-run-withno constructor : decl_exit_static_inv_mid ]
- [ subdir-run-withno constructor : decl_exit_static_inv_none ]
+ [ subdir-run constructor : decl_exit_static_inv_all ]
+ [ subdir-run constructor : decl_exit_static_inv_ends ]
+ [ subdir-run constructor : decl_exit_static_inv_mid ]
+ [ subdir-run constructor : decl_exit_static_inv_none ]
# No decl_entry_static_inv_... for constructors.
- [ subdir-run-withno constructor : decl_exit_inv_all ]
- [ subdir-run-withno constructor : decl_exit_inv_ends ]
- [ subdir-run-withno constructor : decl_exit_inv_mid ]
- [ subdir-run-withno constructor : decl_exit_inv_none ]
+ [ subdir-run constructor : decl_exit_inv_all ]
+ [ subdir-run constructor : decl_exit_inv_ends ]
+ [ subdir-run constructor : decl_exit_inv_mid ]
+ [ subdir-run constructor : decl_exit_inv_none ]
- [ subdir-run-withno constructor : bases ]
- [ subdir-run-withno constructor : access ]
- [ subdir-run-withno constructor : no_contracts ]
+ [ subdir-run constructor : bases ]
+ [ subdir-run constructor : access ]
+ [ subdir-run constructor : no_contracts ]
- [ subdir-run-withno constructor : body_throw ]
- [ subdir-run-withno constructor : old_throw ]
+ [ subdir-run constructor : body_throw ]
+ [ subdir-run constructor : old_throw ]
[ subdir-compile-fail constructor : pre_error ]
;
@@ -44,189 +44,196 @@ test-suite destructor
:
# No decl_pre_... for destructors.
- [ subdir-run-withno destructor : decl_post_all ]
- [ subdir-run-withno destructor : decl_post_ends ]
- [ subdir-run-withno destructor : decl_post_mid ]
- [ subdir-run-withno destructor : decl_post_none ]
+ [ subdir-run destructor : decl_post_all ]
+ [ subdir-run destructor : decl_post_ends ]
+ [ subdir-run destructor : decl_post_mid ]
+ [ subdir-run destructor : decl_post_none ]
- [ subdir-run-withno destructor : decl_entry_static_inv_all ]
- [ subdir-run-withno destructor : decl_entry_static_inv_ends ]
- [ subdir-run-withno destructor : decl_entry_static_inv_mid ]
- [ subdir-run-withno destructor : decl_entry_static_inv_none ]
+ [ subdir-run destructor : decl_entry_static_inv_all ]
+ [ subdir-run destructor : decl_entry_static_inv_ends ]
+ [ subdir-run destructor : decl_entry_static_inv_mid ]
+ [ subdir-run destructor : decl_entry_static_inv_none ]
- [ subdir-run-withno destructor : decl_exit_static_inv_all ]
- [ subdir-run-withno destructor : decl_exit_static_inv_ends ]
- [ subdir-run-withno destructor : decl_exit_static_inv_mid ]
- [ subdir-run-withno destructor : decl_exit_static_inv_none ]
+ [ subdir-run destructor : decl_exit_static_inv_all ]
+ [ subdir-run destructor : decl_exit_static_inv_ends ]
+ [ subdir-run destructor : decl_exit_static_inv_mid ]
+ [ subdir-run destructor : decl_exit_static_inv_none ]
- [ subdir-run-withno destructor : decl_entry_inv_all ]
- [ subdir-run-withno destructor : decl_entry_inv_ends ]
- [ subdir-run-withno destructor : decl_entry_inv_mid ]
- [ subdir-run-withno destructor : decl_entry_inv_none ]
+ [ subdir-run destructor : decl_entry_inv_all ]
+ [ subdir-run destructor : decl_entry_inv_ends ]
+ [ subdir-run destructor : decl_entry_inv_mid ]
+ [ subdir-run destructor : decl_entry_inv_none ]
# No decl_exit_inv_... for destructors.
- [ subdir-run-withno destructor : bases ]
- [ subdir-run-withno destructor : access ]
- [ subdir-run-withno destructor : no_contracts ]
+ [ subdir-run destructor : bases ]
+ [ subdir-run destructor : access ]
+ [ subdir-run destructor : no_contracts ]
- [ subdir-run-withno destructor : body_throw ]
- [ subdir-run-withno destructor : old_throw ]
+ [ subdir-run destructor : body_throw ]
+ [ subdir-run destructor : old_throw ]
[ subdir-compile-fail destructor : pre_error ]
;
test-suite public_function
:
- [ subdir-run-withno public_function : decl_pre_all ]
- [ subdir-run-withno public_function : decl_pre_ends ]
- [ subdir-run-withno public_function : decl_pre_mid ]
- [ subdir-run-withno public_function : decl_pre_none ]
+ [ subdir-run public_function : decl_pre_all ]
+ [ subdir-run public_function : decl_pre_ends ]
+ [ subdir-run public_function : decl_pre_mid ]
+ [ subdir-run public_function : decl_pre_none ]
- [ subdir-run-withno public_function : decl_post_all ]
- [ subdir-run-withno public_function : decl_post_ends ]
- [ subdir-run-withno public_function : decl_post_mid ]
- [ subdir-run-withno public_function : decl_post_none ]
+ [ subdir-run public_function : decl_post_all ]
+ [ subdir-run public_function : decl_post_ends ]
+ [ subdir-run public_function : decl_post_mid ]
+ [ subdir-run public_function : decl_post_none ]
- [ subdir-run-withno public_function : decl_entry_static_inv_all ]
- [ subdir-run-withno public_function : decl_entry_static_inv_ends ]
- [ subdir-run-withno public_function : decl_entry_static_inv_mid ]
- [ subdir-run-withno public_function : decl_entry_static_inv_none ]
+ [ subdir-run public_function : decl_entry_static_inv_all ]
+ [ subdir-run public_function : decl_entry_static_inv_ends ]
+ [ subdir-run public_function : decl_entry_static_inv_mid ]
+ [ subdir-run public_function : decl_entry_static_inv_none ]
- [ subdir-run-withno public_function : decl_exit_static_inv_all ]
- [ subdir-run-withno public_function : decl_exit_static_inv_ends ]
- [ subdir-run-withno public_function : decl_exit_static_inv_mid ]
- [ subdir-run-withno public_function : decl_exit_static_inv_none ]
+ [ subdir-run public_function : decl_exit_static_inv_all ]
+ [ subdir-run public_function : decl_exit_static_inv_ends ]
+ [ subdir-run public_function : decl_exit_static_inv_mid ]
+ [ subdir-run public_function : decl_exit_static_inv_none ]
- [ subdir-run-withno public_function : decl_entry_inv_all ]
- [ subdir-run-withno public_function : decl_entry_inv_ends ]
- [ subdir-run-withno public_function : decl_entry_inv_mid ]
- [ subdir-run-withno public_function : decl_entry_inv_none ]
+ [ subdir-run public_function : decl_entry_inv_all ]
+ [ subdir-run public_function : decl_entry_inv_ends ]
+ [ subdir-run public_function : decl_entry_inv_mid ]
+ [ subdir-run public_function : decl_entry_inv_none ]
- [ subdir-run-withno public_function : decl_exit_inv_all ]
- [ subdir-run-withno public_function : decl_exit_inv_ends ]
- [ subdir-run-withno public_function : decl_exit_inv_mid ]
- [ subdir-run-withno public_function : decl_exit_inv_none ]
+ [ subdir-run public_function : decl_exit_inv_all ]
+ [ subdir-run public_function : decl_exit_inv_ends ]
+ [ subdir-run public_function : decl_exit_inv_mid ]
+ [ subdir-run public_function : decl_exit_inv_none ]
- [ subdir-run-withno public_function : bases ]
- [ subdir-run-withno public_function : bases_virtual ]
- [ subdir-run-withno public_function : bases_branch ]
- [ subdir-run-withno public_function : bases_sparse ]
- [ subdir-run-withno public_function : bases_protected ]
+ [ subdir-run public_function : bases ]
+ [ subdir-run public_function : bases_virtual ]
+ [ subdir-run public_function : bases_branch ]
+ [ subdir-run public_function : bases_sparse ]
+ [ subdir-run public_function : bases_protected ]
[ subdir-compile-fail public_function : bases_protected_error ]
- [ subdir-run-withno public_function : access ]
- [ subdir-run-withno public_function : no_contracts ]
+ [ subdir-run public_function : access ]
+ [ subdir-run public_function : no_contracts ]
- [ subdir-run-withno public_function : body_throw ]
- [ subdir-run-withno public_function : old_throw ]
+ [ subdir-run public_function : body_throw ]
+ [ subdir-run public_function : old_throw ]
- [ subdir-run-withno public_function : max_args0 ]
- [ subdir-run-withno public_function : max_args0_no_tva ]
- [ subdir-run-withno public_function : max_args1 ]
- [ subdir-run-withno public_function : max_args1_no_tva ]
- [ subdir-run-withno public_function : max_args2 ]
- [ subdir-run-withno public_function : max_args2_no_tva ]
- [ subdir-run-withno public_function : max_args ]
- [ subdir-run-withno public_function : max_args_no_tva ]
+ [ subdir-run public_function : max_args0 ]
+ [ subdir-run public_function : max_args0_no_tva ]
+ [ subdir-run public_function : max_args1 ]
+ [ subdir-run public_function : max_args1_no_tva ]
+ [ subdir-run public_function : max_args2 ]
+ [ subdir-run public_function : max_args2_no_tva ]
+ [ subdir-run public_function : max_args ]
+ [ subdir-run public_function : max_args_no_tva ]
- [ subdir-run-withno public_function : max_bases ]
+ [ subdir-run public_function : max_bases ]
- [ subdir-run-withno public_function : overload ]
- [ subdir-run-withno public_function : overload_no_tva ]
+ [ subdir-run public_function : overload ]
+ [ subdir-run public_function : overload_no_tva ]
[ subdir-compile-fail public_function : override_error ]
- [ subdir-run-withno public_function : override_permissive ]
+ [ subdir-run public_function : override_permissive ]
- [ subdir-run-withno public_function : static ]
- [ subdir-run-withno public_function : static_body_throw ]
- [ subdir-run-withno public_function : static_old_throw ]
- [ subdir-run-withno public_function : static_no_contracts ]
-;
-
-test-suite function
-:
- [ subdir-run-withno function : decl_pre_all ]
- [ subdir-run-withno function : decl_pre_none ]
-
- [ subdir-run-withno function : decl_post_all ]
- [ subdir-run-withno function : decl_post_none ]
-
- [ subdir-run-withno function : func ]
- [ subdir-run-withno function : no_contracts ]
-
- [ subdir-run-withno function : body_throw ]
- [ subdir-run-withno function : old_throw ]
+ [ subdir-run public_function : static ]
+ [ subdir-run public_function : static_body_throw ]
+ [ subdir-run public_function : static_old_throw ]
+ [ subdir-run public_function : static_no_contracts ]
;
test-suite invariant
:
- [ subdir-run-withno invariant : decl_static_cv_const ]
- [ subdir-run-withno invariant : decl_static_cv ]
- [ subdir-run-withno invariant : decl_cv_const ]
- [ subdir-run-withno invariant : decl_static_const ]
- [ subdir-run-withno invariant : decl_static ]
- [ subdir-run-withno invariant : decl_cv ]
- [ subdir-run-withno invariant : decl_const ]
- [ subdir-run-withno invariant : decl_nothing ]
+ [ subdir-run invariant : decl_static_cv_const ]
+ [ subdir-run invariant : decl_static_cv ]
+ [ subdir-run invariant : decl_cv_const ]
+ [ subdir-run invariant : decl_static_const ]
+ [ subdir-run invariant : decl_static ]
+ [ subdir-run invariant : decl_cv ]
+ [ subdir-run invariant : decl_const ]
+ [ subdir-run invariant : decl_nothing ]
[ subdir-compile-fail invariant : static_inv_mutable_error ]
- [ subdir-run-withno invariant : static_inv_mutable_permissive ]
+ [ subdir-run invariant : static_inv_mutable_permissive ]
[ subdir-compile-fail invariant : static_inv_const_error ]
- [ subdir-run-withno invariant : static_inv_const_permissive ]
+ [ subdir-run invariant : static_inv_const_permissive ]
[ subdir-compile-fail invariant : static_inv_volatile_error ]
- [ subdir-run-withno invariant : static_inv_volatile_permissive ]
+ [ subdir-run invariant : static_inv_volatile_permissive ]
[ subdir-compile-fail invariant : static_inv_cv_error ]
- [ subdir-run-withno invariant : static_inv_cv_permissive ]
+ [ subdir-run invariant : static_inv_cv_permissive ]
[ subdir-compile-fail invariant : inv_static_error ]
- [ subdir-run-withno invariant : inv_static_permissive ]
+ [ subdir-run invariant : inv_static_permissive ]
[ subdir-compile-fail invariant : inv_mutable_error ]
- [ subdir-run-withno invariant : inv_mutable_permissive ]
+ [ subdir-run invariant : inv_mutable_permissive ]
[ subdir-compile-fail invariant : inv_volatile_error ]
- [ subdir-run-withno invariant : inv_volatile_permissive ]
+ [ subdir-run invariant : inv_volatile_permissive ]
;
+
+test-suite function
+:
+ [ subdir-run function : decl_pre_all ]
+ [ subdir-run function : decl_pre_none ]
+ [ subdir-run function : decl_post_all ]
+ [ subdir-run function : decl_post_none ]
+
+ [ subdir-run function : func ]
+ [ subdir-run function : no_contracts ]
+
+ [ subdir-run function : body_throw ]
+ [ subdir-run function : old_throw ]
+;
+
test-suite result
:
- [ subdir-run-withno result : mixed_optional ]
- [ subdir-run-withno result : mixed_optional_ref ]
+ [ subdir-run result : mixed_optional ]
+ [ subdir-run result : mixed_optional_ref ]
[ subdir-compile-fail result : type_mismatch_error ]
;
test-suite old
:
- [ subdir-run-withno old : auto ]
+ [ subdir-run old : auto ]
- [ subdir-run-withno old : no_macros ]
+ [ subdir-run old : no_macros ]
[ subdir-compile-fail old : no_make_old_error ]
- [ subdir-run-withno old : noncopyable ]
+ [ subdir-run old : noncopyable ]
[ subdir-compile-fail old : noncopyable_error ]
- [ subdir-run-withno old : no_equal ]
+ [ subdir-run old : no_equal ]
[ subdir-compile-fail old : no_equal_error ]
;
test-suite disable
:
- [ subdir-run-withno disable : checking ]
- [ subdir-run-withno disable : checking_pre_disable_nothing ]
+ [ subdir-run disable : prog ]
+ [ subdir-run disable : prog_pre_disable_nothing ]
+
+ [ subdir-lib disable : lib_a :
+ shared:BOOST_CONTRACT_TEST_LIB_A_DYN_LINK ]
+ [ subdir-lib disable : lib_b : disable-lib_a
+ shared:BOOST_CONTRACT_TEST_LIB_B_DYN_LINK ]
+ [ subdir-run disable : libs :
+ disable-lib_a disable-lib_b ]
;
test-suite set
:
- [ subdir-run-withno set : pre_old_post ]
- [ subdir-run-withno set : pre_old ]
- [ subdir-run-withno set : old_post ]
- [ subdir-run-withno set : pre_post ]
- [ subdir-run-withno set : pre ]
- [ subdir-run-withno set : old ]
- [ subdir-run-withno set : post ]
- [ subdir-run-withno set : nothing ]
+ [ subdir-run set : pre_old_post ]
+ [ subdir-run set : pre_old ]
+ [ subdir-run set : old_post ]
+ [ subdir-run set : pre_post ]
+ [ subdir-run set : pre ]
+ [ subdir-run set : old ]
+ [ subdir-run set : post ]
+ [ subdir-run set : nothing ]
- [ subdir-run-withno set : no_guard ]
+ [ subdir-run set : no_guard ]
[ subdir-compile-fail set : old_pre_error ]
[ subdir-compile-fail set : post_old_error ]
@@ -244,7 +251,7 @@ test-suite call_if
[ subdir-run call_if : equal_to ]
;
-# C++14 supported only by Clang... so in its own suite and explicit.
+# C++14 supported only by Clang... so in its own test-suite and explicit.
test-suite cxx14
:
[ subdir-run call_if : equal_to_cxx14 :
diff --git a/test/aux_/oteststream.hpp b/test/aux_/oteststream.hpp
index 4e2cba7..a01540c 100644
--- a/test/aux_/oteststream.hpp
+++ b/test/aux_/oteststream.hpp
@@ -35,8 +35,10 @@ struct oteststream :
std::string str() const { return oss_.str(); }
void str(std::string const& s) { oss_.str(s); }
- bool eq(std::string const& s) { // Also display mismatching characters.
- std::string r = str();
+ bool eq(std::string const& s) { return eq(str(), s); }
+
+ // Also display mismatching characters.
+ static bool eq(std::string const& r, std::string const& s) {
std::string::size_type i = 0;
for(; i < r.size() && i < s.size(); ++i) if(r[i] != s[i]) break;
if(i < r.size() || i < s.size()) {
diff --git a/test/constructor/bases.cpp b/test/constructor/bases.cpp
index f1a7575..f949c2d 100644
--- a/test/constructor/bases.cpp
+++ b/test/constructor/bases.cpp
@@ -347,7 +347,6 @@ int main() {
BOOST_TEST_EQ(a::x_type::evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors()); // No leak.
- // TODO: I should check these ctors() == dtors() every where cnt_type is used, in all tests.
BOOST_TEST_EQ(c::y_type::copies(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
diff --git a/test/disable/checking.cpp b/test/disable/checking.cpp
deleted file mode 100644
index 3204259..0000000
--- a/test/disable/checking.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-
-// Test other contract checking disabled within contract checking.
-
-#undef BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING
-#include "checking.hpp"
-
diff --git a/test/disable/checking.hpp b/test/disable/checking.hpp
deleted file mode 100644
index 54d85bc..0000000
--- a/test/disable/checking.hpp
+++ /dev/null
@@ -1,162 +0,0 @@
-
-// Test contract checking and old value copies disabled within contracts.
-
-#include "../aux_/oteststream.hpp"
-#include "../aux_/counter.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-
-boost::contract::test::aux::oteststream out;
-
-struct a {
- static void static_invariant() { out << "a::static_inv" << std::endl; }
- void invariant() const { out << "a::inv" << std::endl; }
-
- struct x_tag;
- typedef boost::contract::test::aux::counter x_type;
-
- int f(x_type& x) {
- int result;
- boost::contract::old_ptr old_x = BOOST_CONTRACT_OLDOF(
- x_type::eval(x));
- boost::contract::guard c = boost::contract::public_function(this)
- .precondition([&] { out << "a::f::pre" << std::endl; })
- .old([&] { out << "a::f::old" << std::endl; })
- .postcondition([&] {
- out << "a::f::post" << std::endl;
- BOOST_CONTRACT_ASSERT(x.value == -old_x->value);
- BOOST_CONTRACT_ASSERT(result == old_x->value);
- })
- ;
- out << "a::f::body" << std::endl;
- result = x.value;
- x.value = -x.value;
- return result;
- }
-};
-
-bool call_f() {
- a aa;
- a::x_type x; x.value = -123;
- return aa.f(x) == -123;
-}
-
-struct b {
- static void static_invariant() { out << "b::static_inv" << std::endl; }
- void invariant() const { out << "b::inv" << std::endl; }
-
- void g() {
- boost::contract::guard c = boost::contract::public_function(this)
- .precondition([&] {
- out << "b::g::pre" << std::endl;
- BOOST_CONTRACT_ASSERT(call_f());
- })
- .old([&] { out << "b::g::old" << std::endl; })
- .postcondition([&] {
- out << "b::g::post" << std::endl;
- BOOST_CONTRACT_ASSERT(call_f());
- })
- ;
- out << "b::g::body" << std::endl;
- }
-};
-
-int main() {
- std::ostringstream ok;
- b bb;
-
- out.str("");
- bb.g();
- ok.str(""); ok
- #if BOOST_CONTRACT_ENTRY_INVARIANTS
- << "b::static_inv" << std::endl
- << "b::inv" << std::endl
- #endif
- #if BOOST_CONTRACT_PRECONDITIONS
- << "b::g::pre" << std::endl
- #ifndef BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING
- // Test call while checking executes body (but no contracts).
- << "a::f::body" << std::endl
- #else
- // Test preconditions have disabled no contract.
- #if BOOST_CONTRACT_ENTRY_INVARIANTS
- << "a::static_inv" << std::endl
- << "a::inv" << std::endl
- #endif
- << "a::f::pre" << std::endl
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "a::f::old" << std::endl
- #endif
- << "a::f::body" << std::endl
- #if BOOST_CONTRACT_EXIT_INVARIANTS
- << "a::static_inv" << std::endl
- << "a::inv" << std::endl
- #endif
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "a::f::post" << std::endl
- #endif
- #endif
- #endif
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "b::g::old" << std::endl
- #endif
- << "b::g::body" << std::endl
- #if BOOST_CONTRACT_EXIT_INVARIANTS
- << "b::static_inv" << std::endl
- << "b::inv" << std::endl
- #endif
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "b::g::post" << std::endl
- // Test call while checking executes body (but no contracts).
- << "a::f::body" << std::endl
- #endif
- ;
- BOOST_TEST(out.eq(ok.str()));
-
- // Test old values not copied for disabled contracts.
- unsigned const cnt =
- #if defined(BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING) && \
- BOOST_CONTRACT_PRECONDITIONS && BOOST_CONTRACT_POSTCONDITIONS
- 1
- #else
- 0
- #endif
- ;
- BOOST_TEST_EQ(a::x_type::copies(), cnt);
- BOOST_TEST_EQ(a::x_type::evals(), cnt);
- BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors());
-
- out << std::endl;
-
- out.str("");
- call_f();
- // Double check a call to f outside another contract checks f's contracts.
- ok.str(""); ok
- #if BOOST_CONTRACT_ENTRY_INVARIANTS
- << "a::static_inv" << std::endl
- << "a::inv" << std::endl
- #endif
- #if BOOST_CONTRACT_PRECONDITIONS
- << "a::f::pre" << std::endl
- #endif
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "a::f::old" << std::endl
- #endif
- << "a::f::body" << std::endl
- #if BOOST_CONTRACT_EXIT_INVARIANTS
- << "a::static_inv" << std::endl
- << "a::inv" << std::endl
- #endif
- #if BOOST_CONTRACT_POSTCONDITIONS
- << "a::f::post" << std::endl
- #endif
- ;
- BOOST_TEST(out.eq(ok.str()));
-
- return boost::report_errors();
-}
-
diff --git a/test/disable/lib_a.cpp b/test/disable/lib_a.cpp
new file mode 100644
index 0000000..08945a6
--- /dev/null
+++ b/test/disable/lib_a.cpp
@@ -0,0 +1,6 @@
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#define BOOST_CONTRACT_TEST_LIB_A_SOURCE
+#include "lib_a_inlined.hpp"
+
diff --git a/test/disable/lib_a.hpp b/test/disable/lib_a.hpp
new file mode 100644
index 0000000..a5c2a06
--- /dev/null
+++ b/test/disable/lib_a.hpp
@@ -0,0 +1,42 @@
+
+#ifndef BOOST_CONTRACT_TEST_LIB_A_HPP_
+#define BOOST_CONTRACT_TEST_LIB_A_HPP_
+
+#include "../aux_/counter.hpp"
+#include
+#include
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#ifdef BOOST_CONTRACT_TEST_LIB_A_DYN_LINK
+ #ifdef BOOST_CONTRACT_TEST_LIB_A_SOURCE
+ #define BOOST_CONTRACT_TEST_LIB_A_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_CONTRACT_TEST_LIB_A_DECL BOOST_SYMBOL_IMPORT
+ #endif
+#else
+ #define BOOST_CONTRACT_TEST_LIB_A_DECL /* nothing */
+#endif
+
+void BOOST_CONTRACT_TEST_LIB_A_DECL out(std::string const& text);
+bool BOOST_CONTRACT_TEST_LIB_A_DECL out_eq(std::string const& text);
+
+struct BOOST_CONTRACT_TEST_LIB_A_DECL a {
+ static void static_invariant();
+ void invariant() const;
+
+ struct x_tag;
+ typedef boost::contract::test::aux::counter x_type;
+
+ int f(x_type& x);
+
+ static void disable_pre_failure();
+ static void disable_post_failure();
+ static void disable_entry_inv_failure();
+ static void disable_exit_inv_failure();
+ static void disable_inv_failure();
+ static void disable_failure();
+};
+
+#endif // #include guard
+
diff --git a/test/disable/lib_a_inlined.hpp b/test/disable/lib_a_inlined.hpp
new file mode 100644
index 0000000..b4d4dd5
--- /dev/null
+++ b/test/disable/lib_a_inlined.hpp
@@ -0,0 +1,81 @@
+
+#ifndef BOOST_TEST_LIB_A_INLINED_HPP_
+#define BOOST_TEST_LIB_A_INLINED_HPP_
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#include "lib_a.hpp"
+#include "../aux_/oteststream.hpp"
+#include
+#include
+#include
+#include
+
+std::string out_;
+
+void out(std::string const& text) {
+ if(text == "") out_ = "";
+ else {
+ out_ = out_ + text;
+ std::clog << text;
+ }
+}
+
+bool out_eq(std::string const& text) {
+ return boost::contract::test::aux::oteststream::eq(out_, text);
+}
+
+void a::static_invariant() { out("a::static_inv\n"); }
+void a::invariant() const { out("a::inv\n"); }
+
+int a::f(x_type& x) {
+ int result;
+ boost::contract::old_ptr old_x = BOOST_CONTRACT_OLDOF(
+ x_type::eval(x));
+ boost::contract::guard c = boost::contract::public_function(this)
+ .precondition([&] { out("a::f::pre\n"); })
+ .old([&] { out("a::f::old\n"); })
+ .postcondition([&] {
+ out("a::f::post\n");
+ BOOST_CONTRACT_ASSERT(x.value == -old_x->value);
+ BOOST_CONTRACT_ASSERT(result == old_x->value);
+ })
+ ;
+ out("a::f::body\n");
+ result = x.value;
+ x.value = -x.value;
+ return result;
+}
+
+void a::disable_pre_failure() {
+ boost::contract::set_precondition_failure([] (boost::contract::from)
+ { out("a::pre_failure"); });
+}
+
+void a::disable_post_failure() {
+ boost::contract::set_postcondition_failure([] (boost::contract::from)
+ { out("a::post_failure"); });
+}
+
+void a::disable_entry_inv_failure() {
+ boost::contract::set_entry_invariant_failure([] (boost::contract::from)
+ { out("a::entry_inv_failure"); });
+}
+
+void a::disable_exit_inv_failure() {
+ boost::contract::set_exit_invariant_failure([] (boost::contract::from)
+ { out("a::exit_inv_failure"); });
+}
+
+void a::disable_inv_failure() {
+ boost::contract::set_invariant_failure([] (boost::contract::from)
+ { out("a::inv_failure"); });
+}
+
+void a::disable_failure() {
+ boost::contract::set_failure([] (boost::contract::from)
+ { out("a::failure"); });
+}
+
+#endif // #include guard
+
diff --git a/test/disable/lib_b.cpp b/test/disable/lib_b.cpp
new file mode 100644
index 0000000..b1936b9
--- /dev/null
+++ b/test/disable/lib_b.cpp
@@ -0,0 +1,6 @@
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#define BOOST_CONTRACT_TEST_LIB_B_SOURCE
+#include "lib_b_inlined.hpp"
+
diff --git a/test/disable/lib_b.hpp b/test/disable/lib_b.hpp
new file mode 100644
index 0000000..2e38042
--- /dev/null
+++ b/test/disable/lib_b.hpp
@@ -0,0 +1,38 @@
+
+#ifndef BOOST_CONTRACT_TEST_LIB_B_HPP_
+#define BOOST_CONTRACT_TEST_LIB_B_HPP_
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#include
+
+#ifdef BOOST_CONTRACT_TEST_LIB_B_DYN_LINK
+ #ifdef BOOST_CONTRACT_TEST_LIB_B_SOURCE
+ #define BOOST_CONTRACT_TEST_LIB_B_DECL BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_CONTRACT_TEST_LIB_B_DECL BOOST_SYMBOL_IMPORT
+ #endif
+#else
+ #define BOOST_CONTRACT_TEST_LIB_B_DECL /* nothing */
+#endif
+
+bool BOOST_CONTRACT_TEST_LIB_B_DECL call_f();
+
+struct BOOST_CONTRACT_TEST_LIB_B_DECL b {
+ static void static_invariant();
+ void invariant() const;
+
+ void g();
+
+ static bool test_disable_pre_failure();
+ static bool test_disable_post_failure();
+ static bool test_disable_entry_inv_failure();
+ static bool test_disable_exit_inv_failure();
+ static bool test_disable_inv_failure();
+ static bool test_disable_failure();
+
+};
+
+#endif // #include guard
+
+
diff --git a/test/disable/lib_b_inlined.hpp b/test/disable/lib_b_inlined.hpp
new file mode 100644
index 0000000..d1a79bb
--- /dev/null
+++ b/test/disable/lib_b_inlined.hpp
@@ -0,0 +1,94 @@
+
+#ifndef BOOST_TEST_LIB_B_INLINED_HPP_
+#define BOOST_TEST_LIB_B_INLINED_HPP_
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#include "lib_b.hpp"
+#include "lib_a.hpp"
+#include
+#include
+#include
+
+bool call_f() {
+ a aa;
+ a::x_type x; x.value = -123;
+ return aa.f(x) == -123;
+}
+
+void b::static_invariant() { out("b::static_inv\n"); }
+void b::invariant() const { out("b::inv\n"); }
+
+void b::g() {
+ boost::contract::guard c = boost::contract::public_function(this)
+ .precondition([&] {
+ out("b::g::pre\n");
+ BOOST_CONTRACT_ASSERT(call_f());
+ })
+ .old([&] { out("b::g::old\n"); })
+ .postcondition([&] {
+ out("b::g::post\n");
+ BOOST_CONTRACT_ASSERT(call_f());
+ })
+ ;
+ out("b::g::body\n");
+}
+
+bool b::test_disable_pre_failure() {
+ a::disable_pre_failure();
+ out("");
+ boost::contract::precondition_failure(boost::contract::from());
+ return out_eq("a::pre_failure");
+}
+
+bool b::test_disable_post_failure() {
+ a::disable_post_failure();
+ out("");
+ boost::contract::postcondition_failure(boost::contract::from());
+ return out_eq("a::post_failure");
+}
+
+bool b::test_disable_entry_inv_failure() {
+ a::disable_entry_inv_failure();
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ return out_eq("a::entry_inv_failure");
+}
+
+bool b::test_disable_exit_inv_failure() {
+ a::disable_exit_inv_failure();
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ return out_eq("a::exit_inv_failure");
+}
+
+bool b::test_disable_inv_failure() {
+ a::disable_inv_failure();
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ bool entry_inv = out_eq("a::inv_failure");
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ bool exit_inv = out_eq("a::inv_failure");
+ return entry_inv && exit_inv;
+}
+
+bool b::test_disable_failure() {
+ a::disable_failure();
+ out("");
+ boost::contract::precondition_failure(boost::contract::from());
+ bool pre = out_eq("a::failure");
+ out("");
+ boost::contract::postcondition_failure(boost::contract::from());
+ bool post = out_eq("a::failure");
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ bool entry_inv = out_eq("a::failure");
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ bool exit_inv = out_eq("a::failure");
+ return pre && post && entry_inv && exit_inv;
+}
+
+#endif // #include guard
+
diff --git a/test/disable/libs.cpp b/test/disable/libs.cpp
new file mode 100644
index 0000000..b001167
--- /dev/null
+++ b/test/disable/libs.cpp
@@ -0,0 +1,5 @@
+
+// Test other contract checking disabled within contract checking among libs.
+
+#include "libs.hpp"
+
diff --git a/test/disable/libs.hpp b/test/disable/libs.hpp
new file mode 100644
index 0000000..12707f5
--- /dev/null
+++ b/test/disable/libs.hpp
@@ -0,0 +1,158 @@
+
+// Test other contract checking disabled within contract checking [among libs].
+
+#include "lib_a.hpp"
+#include "lib_b.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
+
+std::string ok_f() {
+ std::ostringstream ok; ok
+ #if BOOST_CONTRACT_ENTRY_INVARIANTS
+ << "a::static_inv" << std::endl
+ << "a::inv" << std::endl
+ #endif
+ #if BOOST_CONTRACT_PRECONDITIONS
+ << "a::f::pre" << std::endl
+ #endif
+ #if BOOST_CONTRACT_POSTCONDITIONS
+ << "a::f::old" << std::endl
+ #endif
+ << "a::f::body" << std::endl
+ #if BOOST_CONTRACT_EXIT_INVARIANTS
+ << "a::static_inv" << std::endl
+ << "a::inv" << std::endl
+ #endif
+ #if BOOST_CONTRACT_POSTCONDITIONS
+ << "a::f::post" << std::endl
+ #endif
+ ;
+ return ok.str();
+}
+
+int main() {
+ std::ostringstream ok;
+ b bb;
+
+ out("");
+ bb.g();
+ ok.str(""); ok
+ #if BOOST_CONTRACT_ENTRY_INVARIANTS
+ << "b::static_inv" << std::endl
+ << "b::inv" << std::endl
+ #endif
+ #if BOOST_CONTRACT_PRECONDITIONS
+ << "b::g::pre" << std::endl
+ #ifdef BOOST_CONTRACT_HEADER_ONLY
+ // Test preconditions have disabled no contract (incorrect, but
+ // only possible behaviour if shared linking not used ad doc).
+ << ok_f()
+ #elif defined(BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING)
+ // Test preconditions have disabled no contract.
+ << ok_f()
+ #else
+ // Test call while checking executes body (but no contracts).
+ << "a::f::body" << std::endl
+ #endif
+ #endif
+ #if BOOST_CONTRACT_POSTCONDITIONS
+ << "b::g::old" << std::endl
+ #endif
+ << "b::g::body" << std::endl
+ #if BOOST_CONTRACT_EXIT_INVARIANTS
+ << "b::static_inv" << std::endl
+ << "b::inv" << std::endl
+ #endif
+ #if BOOST_CONTRACT_POSTCONDITIONS
+ << "b::g::post" << std::endl
+ #ifdef BOOST_CONTRACT_HEADER_ONLY
+ // Test preconditions have disabled no contract (incorrect, but
+ // only possible behaviour if shared linking not used ad doc).
+ << ok_f()
+ #else
+ // Test call while checking executes body (but no contracts).
+ << "a::f::body" << std::endl
+ #endif
+ #endif
+ ;
+ BOOST_TEST(out_eq(ok.str()));
+
+ // Test old values not copied for disabled contracts.
+ unsigned const cnt =
+ #if defined(BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING) && \
+ BOOST_CONTRACT_PRECONDITIONS && BOOST_CONTRACT_POSTCONDITIONS
+ 1
+ #else
+ 0
+ #endif
+ ;
+ BOOST_TEST_EQ(a::x_type::copies(), cnt);
+ BOOST_TEST_EQ(a::x_type::evals(), cnt);
+ BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors());
+
+ // Double check a call to f outside another contract checks f's contracts.
+ out("");
+ call_f();
+ BOOST_TEST(out_eq(ok_f()));
+
+ // Test setting failure handlers (from this program using a lib).
+
+ a::disable_pre_failure();
+ out("");
+ boost::contract::precondition_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::pre_failure"));
+
+ a::disable_post_failure();
+ out("");
+ boost::contract::postcondition_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::post_failure"));
+
+ a::disable_entry_inv_failure();
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::entry_inv_failure"));
+
+ a::disable_exit_inv_failure();
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::exit_inv_failure"));
+
+ a::disable_inv_failure();
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::inv_failure"));
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::inv_failure"));
+
+ a::disable_failure();
+ out("");
+ boost::contract::precondition_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::failure"));
+ out("");
+ boost::contract::postcondition_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::failure"));
+ out("");
+ boost::contract::entry_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::failure"));
+ out("");
+ boost::contract::exit_invariant_failure(boost::contract::from());
+ BOOST_TEST(out_eq("a::failure"));
+
+
+ // Test setting failure handlers (from a lib using another lib).
+
+ BOOST_TEST(b::test_disable_pre_failure());
+ BOOST_TEST(b::test_disable_post_failure());
+ BOOST_TEST(b::test_disable_entry_inv_failure());
+ BOOST_TEST(b::test_disable_exit_inv_failure());
+ BOOST_TEST(b::test_disable_inv_failure());
+ BOOST_TEST(b::test_disable_failure());
+
+ return boost::report_errors();
+}
+
diff --git a/test/disable/prog.cpp b/test/disable/prog.cpp
new file mode 100644
index 0000000..0350ab9
--- /dev/null
+++ b/test/disable/prog.cpp
@@ -0,0 +1,9 @@
+
+// Test other contract checking disabled within contract checking (in a prog).
+
+#include "lib_a.hpp"
+#include "lib_a_inlined.hpp"
+#include "lib_b.hpp"
+#include "lib_b_inlined.hpp"
+#include "libs.hpp"
+
diff --git a/test/disable/checking_pre_disable_nothing.cpp b/test/disable/prog_pre_disable_nothing.cpp
similarity index 53%
rename from test/disable/checking_pre_disable_nothing.cpp
rename to test/disable/prog_pre_disable_nothing.cpp
index 07c8119..fc2a1c0 100644
--- a/test/disable/checking_pre_disable_nothing.cpp
+++ b/test/disable/prog_pre_disable_nothing.cpp
@@ -2,5 +2,9 @@
// Test other contract checking but pre disabled within contract checking.
#define BOOST_CONTRACT_CONFIG_PRECONDITIONS_DISABLE_NOTHING
-#include "checking.hpp"
+#include "lib_a.hpp"
+#include "lib_a_inlined.hpp"
+#include "lib_b.hpp"
+#include "lib_b_inlined.hpp"
+#include "libs.hpp"
diff --git a/test/public_function/bases.cpp b/test/public_function/bases.cpp
index f7d23b4..8aab1c4 100644
--- a/test/public_function/bases.cpp
+++ b/test/public_function/bases.cpp
@@ -67,35 +67,35 @@ int main() {
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 4, 0));
BOOST_TEST_EQ(s.evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 4, 0));
- BOOST_TEST_EQ(s.ctors(), s.dtors());
+ BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var.
BOOST_TEST_EQ(aa.x.value, "aA");
BOOST_TEST_EQ(aa.x.copies(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
BOOST_TEST_EQ(aa.x.evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
- BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors());
+ BOOST_TEST_EQ(aa.x.ctors(), aa.x.dtors() + 1); // 1 for member var.
BOOST_TEST_EQ(aa.y.value, "cA");
BOOST_TEST_EQ(aa.y.copies(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
BOOST_TEST_EQ(aa.y.evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
- BOOST_TEST_EQ(aa.y.ctors(), aa.y.dtors());
+ BOOST_TEST_EQ(aa.y.ctors(), aa.y.dtors() + 1); // 1 for member var.
BOOST_TEST_EQ(aa.t<'d'>::z.value, "dA");
BOOST_TEST_EQ(aa.t<'d'>::z.copies(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
BOOST_TEST_EQ(aa.t<'d'>::z.evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
- BOOST_TEST_EQ(aa.t<'d'>::z.ctors(), aa.t<'d'>::z.dtors());
+ BOOST_TEST_EQ(aa.t<'d'>::z.ctors(), aa.t<'d'>::z.dtors() + 1); // 1 member.
BOOST_TEST_EQ(aa.t<'e'>::z.value, "eA");
BOOST_TEST_EQ(aa.t<'e'>::z.copies(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
BOOST_TEST_EQ(aa.t<'e'>::z.evals(),
BOOST_PP_IIF(BOOST_CONTRACT_POSTCONDITIONS, 1, 0));
- BOOST_TEST_EQ(aa.t<'e'>::z.ctors(), aa.t<'e'>::z.dtors());
+ BOOST_TEST_EQ(aa.t<'e'>::z.ctors(), aa.t<'e'>::z.dtors() + 1); // 1 member.
return boost::report_errors();
}
diff --git a/test/result/mixed_optional.hpp b/test/result/mixed_optional.hpp
index 236a1f9..a658dbc 100644
--- a/test/result/mixed_optional.hpp
+++ b/test/result/mixed_optional.hpp
@@ -29,7 +29,7 @@ typedef boost::contract::test::aux::counter ch_type;
#else // Test with result types by value.
#define BOOST_CONTRACT_TEST_CH_TYPE ch_type
#define BOOST_CONTRACT_TEST_CH_INIT /* nothing */
- unsigned const ch_extras = 1; // Only 1 local (no global) var.
+ unsigned const ch_extras = 1; // 1 for local var (no global var).
#endif
bool tested_d_copies = false;