summaryrefslogtreecommitdiff
path: root/boost/contract/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/contract/detail')
-rw-r--r--boost/contract/detail/assert.hpp28
-rw-r--r--boost/contract/detail/auto_ptr.hpp53
-rw-r--r--boost/contract/detail/check.hpp48
-rw-r--r--boost/contract/detail/checking.hpp80
-rw-r--r--boost/contract/detail/condition/cond_base.hpp153
-rw-r--r--boost/contract/detail/condition/cond_inv.hpp232
-rw-r--r--boost/contract/detail/condition/cond_post.hpp88
-rw-r--r--boost/contract/detail/condition/cond_subcontracting.hpp472
-rw-r--r--boost/contract/detail/config.hpp26
-rw-r--r--boost/contract/detail/debug.hpp20
-rw-r--r--boost/contract/detail/decl.hpp129
-rw-r--r--boost/contract/detail/declspec.hpp51
-rw-r--r--boost/contract/detail/inlined.hpp15
-rw-r--r--boost/contract/detail/inlined/core/exception.hpp502
-rw-r--r--boost/contract/detail/inlined/detail/checking.hpp49
-rw-r--r--boost/contract/detail/inlined/old.hpp34
-rw-r--r--boost/contract/detail/name.hpp26
-rw-r--r--boost/contract/detail/none.hpp28
-rw-r--r--boost/contract/detail/noop.hpp19
-rw-r--r--boost/contract/detail/operation/constructor.hpp95
-rw-r--r--boost/contract/detail/operation/destructor.hpp102
-rw-r--r--boost/contract/detail/operation/function.hpp82
-rw-r--r--boost/contract/detail/operation/public_function.hpp161
-rw-r--r--boost/contract/detail/operation/static_public_function.hpp103
-rw-r--r--boost/contract/detail/operator_safe_bool.hpp73
-rw-r--r--boost/contract/detail/preprocessor/keyword/private.hpp35
-rw-r--r--boost/contract/detail/preprocessor/keyword/protected.hpp36
-rw-r--r--boost/contract/detail/preprocessor/keyword/public.hpp35
-rw-r--r--boost/contract/detail/preprocessor/keyword/utility/is.hpp30
-rw-r--r--boost/contract/detail/preprocessor/keyword/virtual.hpp35
-rw-r--r--boost/contract/detail/static_local_var.hpp41
-rw-r--r--boost/contract/detail/tvariadic.hpp190
-rw-r--r--boost/contract/detail/type_traits/member_function_types.hpp72
-rw-r--r--boost/contract/detail/type_traits/mirror.hpp111
-rw-r--r--boost/contract/detail/type_traits/optional.hpp42
35 files changed, 3296 insertions, 0 deletions
diff --git a/boost/contract/detail/assert.hpp b/boost/contract/detail/assert.hpp
new file mode 100644
index 0000000000..e44726733e
--- /dev/null
+++ b/boost/contract/detail/assert.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_ASSERT_HPP_
+#define BOOST_CONTRACT_DETAIL_ASSERT_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/detail/noop.hpp>
+#include <boost/preprocessor/stringize.hpp>
+
+// In detail because used by both ASSERT and CHECK.
+// Use ternary operator `?:` and no trailing `;` here to allow `if(...) ASSERT(
+// ...); else ...` (won't compile if expands using an if statement instead even
+// if wrapped by {}, and else won't compile if expands trailing `;`).
+#define BOOST_CONTRACT_DETAIL_ASSERT(cond) \
+ /* no if-statement here */ \
+ ((cond) ? \
+ BOOST_CONTRACT_DETAIL_NOOP \
+ : \
+ throw boost::contract::assertion_failure( \
+ __FILE__, __LINE__, BOOST_PP_STRINGIZE(cond)) \
+ ) /* no ; here */
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/auto_ptr.hpp b/boost/contract/detail/auto_ptr.hpp
new file mode 100644
index 0000000000..e76945ce9c
--- /dev/null
+++ b/boost/contract/detail/auto_ptr.hpp
@@ -0,0 +1,53 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_AUTO_PTR_HPP_
+#define BOOST_CONTRACT_DETAIL_AUTO_PTR_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
+
+#include <boost/contract/detail/operator_safe_bool.hpp>
+#include <boost/contract/detail/debug.hpp>
+#include <boost/config.hpp>
+
+namespace boost { namespace contract { namespace detail {
+
+// Using this instead of std::auto_ptr because std::auto_ptr will be removed in
+// C++17 (this library always uses release() to avoid ownership issues).
+template<typename T>
+class auto_ptr { // Copyable (using default copy operations).
+public:
+ explicit auto_ptr(T* ptr = 0) : ptr_(ptr) {}
+
+ ~auto_ptr() BOOST_NOEXCEPT_IF(false) { delete ptr_; }
+
+ T* release() {
+ T* ptr = ptr_;
+ ptr_ = 0;
+ return ptr;
+ }
+
+ T& operator*() {
+ BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
+ return *ptr_;
+ }
+
+ T const& operator*() const {
+ BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
+ return *ptr_;
+ }
+
+ T* operator->() { return ptr_; }
+ T const* operator->() const { return ptr_; }
+
+ BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(auto_ptr<T>, !!ptr_)
+
+private:
+ T* ptr_;
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/check.hpp b/boost/contract/detail/check.hpp
new file mode 100644
index 0000000000..49006d92d7
--- /dev/null
+++ b/boost/contract/detail/check.hpp
@@ -0,0 +1,48 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_CHECK_HPP_
+#define BOOST_CONTRACT_DETAIL_CHECK_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
+
+#include <boost/contract/core/config.hpp>
+#ifndef BOOST_CONTRACT_NO_CHECKS
+ #include <boost/contract/core/exception.hpp>
+
+ /* PRIVATE */
+
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ #include <boost/contract/detail/checking.hpp>
+ #include <boost/contract/detail/name.hpp>
+
+ #define BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ \
+ if(!boost::contract::detail::checking::already())
+ #define BOOST_CONTRACT_CHECK_CHECKING_VAR_(guard) \
+ /* this name somewhat unique to min var shadow warnings */ \
+ boost::contract::detail::checking BOOST_CONTRACT_DETAIL_NAME2( \
+ guard, __LINE__);
+ #else
+ #define BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ /* nothing */
+ #define BOOST_CONTRACT_CHECK_CHECKING_VAR_(guard) /* nothing */
+ #endif
+
+ /* PUBLIC */
+
+ #define BOOST_CONTRACT_DETAIL_CHECK(assertion) \
+ { \
+ try { \
+ BOOST_CONTRACT_CHECK_IF_NOT_CHECKING_ALREADY_ \
+ { \
+ BOOST_CONTRACT_CHECK_CHECKING_VAR_(k) \
+ { assertion; } \
+ } \
+ } catch(...) { boost::contract::check_failure(); } \
+ }
+#else
+ #define BOOST_CONTRACT_DETAIL_CHECK(assertion) {}
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/checking.hpp b/boost/contract/detail/checking.hpp
new file mode 100644
index 0000000000..765c04f4f8
--- /dev/null
+++ b/boost/contract/detail/checking.hpp
@@ -0,0 +1,80 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_CHECKING_HPP_
+#define BOOST_CONTRACT_DETAIL_CHECKING_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
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/static_local_var.hpp>
+#include <boost/contract/detail/declspec.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace boost { namespace contract { namespace detail {
+
+#ifdef BOOST_MSVC
+ #pragma warning(push)
+ #pragma warning(disable: 4251) // Member w/o DLL spec (mutex_ type).
+#endif
+
+// RAII facility to disable assertions while checking other assertions.
+class BOOST_CONTRACT_DETAIL_DECLSPEC checking :
+ private boost::noncopyable // Non-copyable resource (might use mutex, etc.).
+{
+public:
+ explicit checking() {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ init_locked();
+ #else
+ init_unlocked();
+ #endif
+ }
+
+ ~checking() {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ done_locked();
+ #else
+ done_unlocked();
+ #endif
+ }
+
+ static bool already() {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return already_locked();
+ #else
+ return already_unlocked();
+ #endif
+ }
+
+private:
+ void init_unlocked();
+ void init_locked();
+
+ void done_unlocked();
+ void done_locked();
+
+ static bool already_unlocked();
+ static bool already_locked();
+
+ struct mutex_tag;
+ typedef static_local_var<mutex_tag, boost::mutex> mutex;
+
+ struct checking_tag;
+ typedef static_local_var_init<checking_tag, bool, bool, false> flag;
+};
+
+#ifdef BOOST_MSVC
+ #pragma warning(pop)
+#endif
+
+} } } // namespace
+
+#ifdef BOOST_CONTRACT_HEADER_ONLY
+ #include <boost/contract/detail/inlined/detail/checking.hpp>
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/condition/cond_base.hpp b/boost/contract/detail/condition/cond_base.hpp
new file mode 100644
index 0000000000..c3f4090461
--- /dev/null
+++ b/boost/contract/detail/condition/cond_base.hpp
@@ -0,0 +1,153 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_COND_BASE_HPP_
+#define BOOST_CONTRACT_DETAIL_COND_BASE_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
+
+// NOTE: It seemed not possible to implement this library without inheritance
+// here because some sort of base type needs to be used to hold contract objects
+// in instances of boost::contract::check while polymorphically calling
+// init and destructor functions to check contracts at entry and exit. This
+// could be possible without inheritance only if boost::contract::check was made
+// a template type but that would complicate user code. In any case, early
+// experimentation with removing this base class and its virtual methods did not
+// seem to reduce compilation and/or run time.
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_OLDS) || \
+ !defined(BOOST_CONTRACT_NO_EXEPTS)
+ #include <boost/function.hpp>
+#endif
+#include <boost/noncopyable.hpp>
+#ifndef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
+ #include <boost/assert.hpp>
+#endif
+#include <boost/config.hpp>
+
+namespace boost { namespace contract { namespace detail {
+
+class cond_base : // Base to hold all contract objects for RAII.
+ private boost::noncopyable // Avoid copying possible user's ftor captures.
+{
+public:
+ explicit cond_base(boost::contract::from from) :
+ BOOST_CONTRACT_ERROR_missing_check_object_declaration(false)
+ , init_asserted_(false)
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ , from_(from)
+ , failed_(false)
+ #endif
+ {}
+
+ // Can override for checking on exit, but should call assert_initialized().
+ virtual ~cond_base() BOOST_NOEXCEPT_IF(false) {
+ // Catch error (but later) even if overrides miss assert_initialized().
+ if(!init_asserted_) assert_initialized();
+ }
+
+ void initialize() { // Must be called by owner ctor (i.e., check class).
+ BOOST_CONTRACT_ERROR_missing_check_object_declaration = true;
+ this->init(); // So all inits (pre, old, post) done after owner decl.
+ }
+
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ template<typename F>
+ void set_pre(F const& f) { pre_ = f; }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ template<typename F>
+ void set_old(F const& f) { old_ = f; }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ template<typename F>
+ void set_except(F const& f) { except_ = f; }
+ #endif
+
+protected:
+ void assert_initialized() { // Derived dtors must assert this at entry.
+ init_asserted_ = true;
+ #ifdef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
+ if(!BOOST_CONTRACT_ERROR_missing_check_object_declaration) {
+ BOOST_CONTRACT_ON_MISSING_CHECK_DECL;
+ }
+ #else
+ // Cannot use a macro instead of this ERROR_... directly here
+ // because assert will not expand it in the error message.
+ BOOST_ASSERT(BOOST_CONTRACT_ERROR_missing_check_object_declaration);
+ #endif
+ }
+
+ virtual void init() {} // Override for checking on entry.
+
+ // Return true if actually checked calling user ftor.
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ bool check_pre(bool throw_on_failure = false) {
+ if(failed()) return true;
+ try { if(pre_) pre_(); else return false; }
+ catch(...) {
+ // Subcontracted pre must throw on failure (instead of
+ // calling failure handler) so to be checked in logic-or.
+ if(throw_on_failure) throw;
+ fail(&boost::contract::precondition_failure);
+ }
+ return true;
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ void copy_old() {
+ if(failed()) return;
+ try { if(old_) old_(); }
+ catch(...) { fail(&boost::contract::old_failure); }
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ void check_except() {
+ if(failed()) return;
+ try { if(except_) except_(); }
+ catch(...) { fail(&boost::contract::except_failure); }
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ void fail(void (*h)(boost::contract::from)) {
+ failed(true);
+ if(h) h(from_);
+ }
+
+ // Virtual so overriding pub func can use virtual_::failed_ instead.
+ virtual bool failed() const { return failed_; }
+ virtual void failed(bool value) { failed_ = value; }
+ #endif
+
+private:
+ bool BOOST_CONTRACT_ERROR_missing_check_object_declaration;
+ bool init_asserted_; // Avoid throwing twice from dtors (undef behavior).
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ boost::contract::from from_;
+ bool failed_;
+ #endif
+ // Following use Boost.Function to handle also lambdas, binds, etc.
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ boost::function<void ()> pre_;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ boost::function<void ()> old_;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ boost::function<void ()> except_;
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/condition/cond_inv.hpp b/boost/contract/detail/condition/cond_inv.hpp
new file mode 100644
index 0000000000..b4c6c03133
--- /dev/null
+++ b/boost/contract/detail/condition/cond_inv.hpp
@@ -0,0 +1,232 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_COND_INV_HPP_
+#define BOOST_CONTRACT_DETAIL_COND_INV_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_post.hpp>
+#ifndef BOOST_CONTRACT_NO_INVARIANTS
+ #include <boost/contract/core/access.hpp>
+ #include <boost/type_traits/add_pointer.hpp>
+ #include <boost/type_traits/is_volatile.hpp>
+ #include <boost/mpl/vector.hpp>
+ #include <boost/mpl/transform.hpp>
+ #include <boost/mpl/for_each.hpp>
+ #include <boost/mpl/copy_if.hpp>
+ #include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/not.hpp>
+ #include <boost/mpl/and.hpp>
+ #include <boost/mpl/placeholders.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #ifndef BOOST_CONTRACT_PERMISSIVE
+ #include <boost/function_types/property_tags.hpp>
+ #include <boost/static_assert.hpp>
+ #endif
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+template<typename VR, class C>
+class cond_inv : public cond_post<VR> { // Non-copyable base.
+ #if !defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ !defined(BOOST_CONTRACT_PERMISSIVE)
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_static_invariant_f<
+ C, void, boost::mpl:: vector<>
+ >::value),
+ "static invariant member function cannot be mutable "
+ "(it must be static instead)"
+ );
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_static_invariant_f<
+ C, void, boost::mpl::vector<>,
+ boost::function_types::const_non_volatile
+ >::value),
+ "static invariant member function cannot be const qualified "
+ "(it must be static instead)"
+ );
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_static_invariant_f<
+ C, void, boost::mpl::vector<>,
+ boost::function_types::volatile_non_const
+ >::value),
+ "static invariant member function cannot be volatile qualified "
+ "(it must be static instead)"
+ );
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_static_invariant_f<
+ C, void, boost::mpl::vector<>,
+ boost::function_types::cv_qualified
+ >::value),
+ "static invariant member function cannot be const volatile "
+ "qualified (it must be static instead)"
+ );
+
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_invariant_s<
+ C, void, boost::mpl::vector<>
+ >::value),
+ "non-static invariant member function cannot be static "
+ "(it must be either const or const volatile qualified instead)"
+ );
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_invariant_f<
+ C, void, boost::mpl::vector<>,
+ boost::function_types::non_cv
+ >::value),
+ "non-static invariant member function cannot be mutable "
+ "(it must be either const or const volatile qualified instead)"
+ );
+ BOOST_STATIC_ASSERT_MSG(
+ (!boost::contract::access::has_invariant_f<
+ C, void, boost::mpl::vector<>,
+ boost::function_types::volatile_non_const
+ >::value),
+ "non-static invariant member function cannot be volatile qualified "
+ "(it must be const or const volatile qualified instead)"
+ );
+ #endif
+
+public:
+ // obj can be 0 for static member functions.
+ explicit cond_inv(boost::contract::from from, C* obj) :
+ cond_post<VR>(from)
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ , obj_(obj)
+ #endif
+ {}
+
+protected:
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ void check_entry_inv() { check_inv(true, false, false); }
+ void check_entry_static_inv() { check_inv(true, true, false); }
+ void check_entry_all_inv() { check_inv(true, false, true); }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ void check_exit_inv() { check_inv(false, false, false); }
+ void check_exit_static_inv() { check_inv(false, true, false); }
+ void check_exit_all_inv() { check_inv(false, false, true); }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ C* object() { return obj_; }
+ #endif
+
+private:
+ #ifndef BOOST_CONTRACT_NO_INVARIANTS
+ // Static, cv, and const inv in that order as strongest qualifier first.
+ void check_inv(bool on_entry, bool static_only, bool const_and_cv) {
+ if(this->failed()) return;
+ try {
+ // Static members only check static inv.
+ check_static_inv<C>();
+ if(!static_only) {
+ if(const_and_cv) {
+ check_cv_inv<C>();
+ check_const_inv<C>();
+ } else if(boost::is_volatile<C>::value) {
+ check_cv_inv<C>();
+ } else {
+ check_const_inv<C>();
+ }
+ }
+ } catch(...) {
+ if(on_entry) {
+ this->fail(&boost::contract::entry_invariant_failure);
+ } else this->fail(&boost::contract::exit_invariant_failure);
+ }
+ }
+
+ template<class C_>
+ typename boost::disable_if<
+ boost::contract::access::has_const_invariant<C_> >::type
+ check_const_inv() {}
+
+ template<class C_>
+ typename boost::enable_if<
+ boost::contract::access::has_const_invariant<C_> >::type
+ check_const_inv() { boost::contract::access::const_invariant(obj_); }
+
+ template<class C_>
+ typename boost::disable_if<
+ boost::contract::access::has_cv_invariant<C_> >::type
+ check_cv_inv() {}
+
+ template<class C_>
+ typename boost::enable_if<
+ boost::contract::access::has_cv_invariant<C_> >::type
+ check_cv_inv() { boost::contract::access::cv_invariant(obj_); }
+
+ template<class C_>
+ typename boost::disable_if<
+ boost::contract::access::has_static_invariant<C_> >::type
+ check_static_inv() {}
+
+ template<class C_>
+ typename boost::enable_if<
+ boost::contract::access::has_static_invariant<C_> >::type
+ check_static_inv() {
+ // SFINAE HAS_STATIC_... returns true even when member is inherited
+ // so extra run-time check here (not the same for non static).
+ if(!inherited<boost::contract::access::has_static_invariant,
+ boost::contract::access::static_invariant_addr>::apply()) {
+ boost::contract::access::static_invariant<C_>();
+ }
+ }
+
+ // Check if class's func is inherited from its base types or not.
+ template<template<class> class HasFunc, template<class> class FuncAddr>
+ struct inherited {
+ static bool apply() {
+ try {
+ boost::mpl::for_each<
+ // For now, no reason to deeply search inheritance tree
+ // (SFINAE HAS_STATIC_... already fails in that case).
+ typename boost::mpl::transform<
+ typename boost::mpl::copy_if<
+ typename boost::mpl::eval_if<boost::contract::
+ access::has_base_types<C>,
+ typename boost::contract::access::
+ base_types_of<C>
+ ,
+ boost::mpl::vector<>
+ >::type,
+ HasFunc<boost::mpl::_1>
+ >::type,
+ boost::add_pointer<boost::mpl::_1>
+ >::type
+ >(compare_func_addr());
+ } catch(signal_equal const&) { return true; }
+ return false;
+ }
+
+ private:
+ class signal_equal {}; // Except. to stop for_each as soon as found.
+
+ struct compare_func_addr {
+ template<typename B>
+ void operator()(B*) {
+ // Inherited func has same addr as in its base.
+ if(FuncAddr<C>::apply() == FuncAddr<B>::apply()) {
+ throw signal_equal();
+ }
+ }
+ };
+ };
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ C* obj_;
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/condition/cond_post.hpp b/boost/contract/detail/condition/cond_post.hpp
new file mode 100644
index 0000000000..aa99a5b9fa
--- /dev/null
+++ b/boost/contract/detail/condition/cond_post.hpp
@@ -0,0 +1,88 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_COND_POST_HPP_
+#define BOOST_CONTRACT_DETAIL_COND_POST_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_base.hpp>
+#include <boost/contract/detail/none.hpp>
+#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ #include <boost/contract/detail/type_traits/optional.hpp>
+ #include <boost/optional.hpp>
+ #include <boost/function.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/mpl/if.hpp>
+#endif
+
+/* PRIVATE */
+
+#define BOOST_CONTRACT_DETAIL_COND_POST_DEF_( \
+ result_type, result_param, ftor_type, ftor_var, ftor_call) \
+ public: \
+ template<typename F> \
+ void set_post(F const& f) { ftor_var = f; } \
+ \
+ protected: \
+ void check_post(result_type const& result_param) { \
+ if(failed()) return; \
+ try { if(ftor_var) { ftor_call; } } \
+ catch(...) { fail(&boost::contract::postcondition_failure); } \
+ } \
+ \
+ private: \
+ boost::function<ftor_type> ftor_var; /* Boost.Func for lambdas, etc. */
+
+/* CODE */
+
+namespace boost { namespace contract { namespace detail {
+
+template<typename VR>
+class cond_post : public cond_base { // Non-copyable base.
+public:
+ explicit cond_post(boost::contract::from from) : cond_base(from) {}
+
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ private: typedef typename boost::mpl::if_<is_optional<VR>,
+ boost::optional<typename boost::remove_reference<typename
+ optional_value_type<VR>::type>::type const&> const&
+ ,
+ VR const&
+ >::type r_type;
+
+ BOOST_CONTRACT_DETAIL_COND_POST_DEF_(
+ r_type,
+ r,
+ void (r_type),
+ // Won't raise this error if NO_POST (for optimization).
+ BOOST_CONTRACT_ERROR_postcondition_result_parameter_required,
+ BOOST_CONTRACT_ERROR_postcondition_result_parameter_required(r)
+ )
+ #endif
+};
+
+template<>
+class cond_post<none> : public cond_base { // Non-copyable base.
+public:
+ explicit cond_post(boost::contract::from from) : cond_base(from) {}
+
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ BOOST_CONTRACT_DETAIL_COND_POST_DEF_(
+ none,
+ unused,
+ void (),
+ // Won't raise this error if NO_POST (for optimization).
+ BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed,
+ BOOST_CONTRACT_ERROR_postcondition_result_parameter_not_allowed()
+ )
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/condition/cond_subcontracting.hpp b/boost/contract/detail/condition/cond_subcontracting.hpp
new file mode 100644
index 0000000000..17d7a6abaa
--- /dev/null
+++ b/boost/contract/detail/condition/cond_subcontracting.hpp
@@ -0,0 +1,472 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_COND_SUBCONTRACTING_HPP_
+#define BOOST_CONTRACT_DETAIL_COND_SUBCONTRACTING_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
+
+#include <boost/contract/core/config.hpp>
+#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/contract/core/exception.hpp>
+#endif
+#include <boost/contract/detail/condition/cond_inv.hpp>
+#include <boost/contract/detail/decl.hpp>
+#include <boost/contract/detail/tvariadic.hpp>
+#ifndef BOOST_CONTRACT_NO_CONDITIONS
+ #include <boost/contract/core/virtual.hpp>
+ #include <boost/contract/core/access.hpp>
+ #include <boost/contract/detail/type_traits/optional.hpp>
+ #include <boost/contract/detail/type_traits/member_function_types.hpp>
+ #include <boost/contract/detail/debug.hpp>
+ #include <boost/contract/detail/none.hpp>
+ #include <boost/contract/detail/name.hpp>
+ #include <boost/type_traits/add_pointer.hpp>
+ #include <boost/mpl/fold.hpp>
+ #include <boost/mpl/contains.hpp>
+ #include <boost/mpl/empty.hpp>
+ #include <boost/mpl/push_back.hpp>
+ #include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/identity.hpp>
+ #include <boost/mpl/placeholders.hpp>
+ #ifndef BOOST_CONTRACT_PERMISSIVE
+ #include <boost/type_traits/is_same.hpp>
+ #include <boost/mpl/or.hpp>
+ #include <boost/mpl/not.hpp>
+ #include <boost/static_assert.hpp>
+ #endif
+ #include <boost/preprocessor/punctuation/comma_if.hpp>
+ #include <boost/config.hpp>
+#endif
+#include <boost/mpl/vector.hpp>
+#if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/mpl/for_each.hpp>
+#endif
+#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ #include <boost/mpl/pop_front.hpp>
+ #include <boost/mpl/front.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOSOT_CONTRACT_NO_EXCEPTS)
+ #include <boost/any.hpp>
+ #include <boost/optional.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #include <typeinfo>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+namespace cond_subcontracting_ {
+ // Exception signals (must not inherit).
+ class signal_no_error {};
+ class signal_not_checked {};
+}
+
+// O, VR, F, and Args-i can be none types (but C cannot).
+BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
+ /* is_friend = */ 0, O, VR, F, C, Args) : public cond_inv<VR, C>
+{ // Non-copyable base.
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ template<class Class, typename Result = boost::mpl::vector<> >
+ class overridden_bases_of {
+ struct search_bases {
+ typedef typename boost::mpl::fold<
+ typename boost::contract::access::base_types_of<Class>::
+ type,
+ Result,
+ // Fold: _1 = result, _2 = current base from base_types.
+ boost::mpl::eval_if<boost::mpl::contains<boost::mpl::_1,
+ boost::add_pointer<boost::mpl::_2> >,
+ boost::mpl::_1 // Base in result, do not add it again.
+ ,
+ boost::mpl::eval_if<
+ typename O::template BOOST_CONTRACT_DETAIL_NAME1(
+ has_member_function)<
+ boost::mpl::_2,
+ typename member_function_types<C, F>::
+ result_type,
+ typename member_function_types<C, F>::
+ virtual_argument_types,
+ typename member_function_types<C, F>::
+ property_tag
+ >
+ ,
+ boost::mpl::push_back<
+ overridden_bases_of<boost::mpl::_2,
+ boost::mpl::_1>,
+ // Bases as * since for_each constructs them.
+ boost::add_pointer<boost::mpl::_2>
+ >
+ ,
+ overridden_bases_of<boost::mpl::_2, boost::mpl::_1>
+ >
+ >
+ >::type type;
+ };
+ public:
+ typedef typename boost::mpl::eval_if<
+ boost::contract::access::has_base_types<Class>,
+ search_bases
+ ,
+ boost::mpl::identity<Result> // Return result (stop recursion).
+ >::type type;
+ };
+
+ typedef typename boost::mpl::eval_if<boost::is_same<O, none>,
+ boost::mpl::vector<>
+ ,
+ overridden_bases_of<C>
+ >::type overridden_bases;
+
+ #ifndef BOOST_CONTRACT_PERMISSIVE
+ BOOST_STATIC_ASSERT_MSG(
+ (boost::mpl::or_<
+ boost::is_same<O, none>,
+ boost::mpl::not_<boost::mpl::empty<overridden_bases> >
+ >::value),
+ "subcontracting function specified as 'override' but does not "
+ "override any contracted member function"
+ );
+ #endif
+ #else
+ typedef boost::mpl::vector<> overridden_bases;
+ #endif
+
+public:
+ explicit cond_subcontracting(
+ boost::contract::from from,
+ boost::contract::virtual_* v,
+ C* obj,
+ VR& r
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, Args, &, args)
+ ) :
+ cond_inv<VR, C>(from, obj)
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ , r_(r)
+ #endif
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, args_, args)
+ #endif
+ {
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ if(v) {
+ base_call_ = true;
+ v_ = v; // Invariant: v_ never null if base_call_.
+ BOOST_CONTRACT_DETAIL_DEBUG(v_);
+ } else {
+ base_call_ = false;
+ if(!boost::mpl::empty<overridden_bases>::value) {
+ v_ = new boost::contract::virtual_(
+ boost::contract::virtual_::no_action);
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ v_->result_ptr_ = &r_;
+ v_->result_type_name_ = typeid(VR).name();
+ v_->result_optional_ = is_optional<VR>::value;
+ #endif
+ } else v_ = 0;
+ }
+ #endif
+ }
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ virtual ~cond_subcontracting() BOOST_NOEXCEPT_IF(false) {
+ if(!base_call_) delete v_;
+ }
+ #endif
+
+protected:
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ void init_subcontracted_old() {
+ // Old values of overloaded func on stack (so no `f` param here).
+ exec_and(boost::contract::virtual_::push_old_init_copy);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ void check_subcontracted_entry_inv() {
+ exec_and(boost::contract::virtual_::check_entry_inv,
+ &cond_subcontracting::check_entry_inv);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ void check_subcontracted_pre() {
+ exec_or(
+ boost::contract::virtual_::check_pre,
+ &cond_subcontracting::check_pre,
+ &boost::contract::precondition_failure
+ );
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ void copy_subcontracted_old() {
+ exec_and(boost::contract::virtual_::call_old_ftor,
+ &cond_subcontracting::copy_virtual_old);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ void check_subcontracted_exit_inv() {
+ exec_and(boost::contract::virtual_::check_exit_inv,
+ &cond_subcontracting::check_exit_inv);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ void check_subcontracted_post() {
+ exec_and(boost::contract::virtual_::check_post,
+ &cond_subcontracting::check_virtual_post);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ void check_subcontracted_except() {
+ exec_and(boost::contract::virtual_::check_except,
+ &cond_subcontracting::check_virtual_except);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ bool base_call() const { return base_call_; }
+
+ bool failed() const /* override */ {
+ if(v_) return v_->failed_;
+ else return cond_base::failed();
+ }
+
+ void failed(bool value) /* override */ {
+ if(v_) v_->failed_ = value;
+ else cond_base::failed(value);
+ }
+ #endif
+
+private:
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ void copy_virtual_old() {
+ boost::contract::virtual_::action_enum a;
+ if(base_call_) {
+ a = v_->action_;
+ v_->action_ = boost::contract::virtual_::push_old_ftor_copy;
+ }
+ this->copy_old();
+ if(base_call_) v_->action_ = a;
+ }
+
+ void pop_base_old() {
+ if(base_call_) {
+ boost::contract::virtual_::action_enum a = v_->action_;
+ v_->action_ = boost::contract::virtual_::pop_old_ftor_copy;
+ this->copy_old();
+ v_->action_ = a;
+ } // Else, do nothing (for base calls only).
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ void check_virtual_post() {
+ pop_base_old();
+ typedef typename boost::remove_reference<typename
+ optional_value_type<VR>::type>::type r_type;
+ boost::optional<r_type const&> r; // No result copy in this code.
+ if(!base_call_) r = optional_get(r_);
+ else if(v_->result_optional_) {
+ try {
+ r = **boost::any_cast<boost::optional<r_type>*>(
+ v_->result_ptr_);
+ } catch(boost::bad_any_cast const&) {
+ try { // Handle optional<...&>.
+ r = **boost::any_cast<boost::optional<r_type&>*>(
+ v_->result_ptr_);
+ } catch(boost::bad_any_cast const&) {
+ try {
+ throw boost::contract::bad_virtual_result_cast(v_->
+ result_type_name_, typeid(r_type).name());
+ } catch(...) {
+ this->fail(&boost::contract::postcondition_failure);
+ }
+ }
+ }
+ } else {
+ try {
+ r = *boost::any_cast<r_type*>(v_->result_ptr_);
+ } catch(boost::bad_any_cast const&) {
+ try {
+ throw boost::contract::bad_virtual_result_cast(
+ v_->result_type_name_, typeid(r_type).name());
+ } catch(...) {
+ this->fail(&boost::contract::postcondition_failure);
+ }
+ }
+ }
+ check_virtual_post_with_result<VR>(r);
+ }
+
+ template<typename R_, typename Result>
+ typename boost::enable_if<is_optional<R_> >::type
+ check_virtual_post_with_result(Result const& r) {
+ this->check_post(r);
+ }
+
+ template<typename R_, typename Result>
+ typename boost::disable_if<is_optional<R_> >::type
+ check_virtual_post_with_result(Result const& r) {
+ BOOST_CONTRACT_DETAIL_DEBUG(r);
+ this->check_post(*r);
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ void check_virtual_except() {
+ pop_base_old();
+ this->check_except();
+ }
+ #endif
+
+ #if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ void exec_and( // Execute action in short-circuit logic-and with bases.
+ boost::contract::virtual_::action_enum a,
+ void (cond_subcontracting::* f)() = 0
+ ) {
+ if(failed()) return;
+ if(!base_call_ || v_->action_ == a) {
+ if(!base_call_ && v_) {
+ v_->action_ = a;
+ boost::mpl::for_each<overridden_bases>(call_base(*this));
+ }
+ if(f) (this->*f)();
+ if(base_call_) {
+ throw cond_subcontracting_::signal_no_error();
+ }
+ }
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ void exec_or( // Execute action in short-circuit logic-or with bases.
+ boost::contract::virtual_::action_enum a,
+ bool (cond_subcontracting::* f)(bool) = 0,
+ void (*h)(boost::contract::from) = 0
+ ) {
+ if(failed()) return;
+ if(!base_call_ || v_->action_ == a) {
+ if(!base_call_ && v_) {
+ v_->action_ = a;
+ try {
+ exec_or_bases<overridden_bases>();
+ return; // A base checked with no error (done).
+ } catch(...) {
+ bool checked = f ? (this->*f)(
+ /* throw_on_failure = */ false) : false;
+ if(!checked) {
+ try { throw; } // Report latest exception found.
+ catch(...) { this->fail(h); }
+ }
+ return; // Checked and no exception (done).
+ }
+ }
+ bool checked = f ?
+ (this->*f)(/* throw_on_failure = */ base_call_) : false;
+ if(base_call_) {
+ if(!checked) {
+ throw cond_subcontracting_::signal_not_checked();
+ }
+ throw cond_subcontracting_::signal_no_error();
+ }
+ }
+ }
+
+ template<typename Bases>
+ typename boost::enable_if<boost::mpl::empty<Bases>, bool>::type
+ exec_or_bases() { return false; }
+
+ template<typename Bases>
+ typename boost::disable_if<boost::mpl::empty<Bases>, bool>::type
+ exec_or_bases() {
+ if(boost::mpl::empty<Bases>::value) return false;
+ try {
+ call_base(*this)(typename boost::mpl::front<Bases>::type());
+ } catch(cond_subcontracting_::signal_not_checked const&) {
+ return exec_or_bases<
+ typename boost::mpl::pop_front<Bases>::type>();
+ } catch(...) {
+ bool checked = false;
+ try {
+ checked = exec_or_bases<
+ typename boost::mpl::pop_front<Bases>::type>();
+ } catch(...) { checked = false; }
+ if(!checked) throw;
+ }
+ return true;
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ class call_base { // Copyable (as &).
+ public:
+ explicit call_base(cond_subcontracting& me) : me_(me) {}
+
+ template<class B>
+ void operator()(B*) {
+ BOOST_CONTRACT_DETAIL_DEBUG(me_.object());
+ BOOST_CONTRACT_DETAIL_DEBUG(me_.v_);
+ BOOST_CONTRACT_DETAIL_DEBUG(me_.v_->action_ !=
+ boost::contract::virtual_::no_action);
+ try {
+ call<B>(BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(
+ Args));
+ } catch(cond_subcontracting_::signal_no_error const&) {
+ // No error (do not throw).
+ }
+ }
+
+ private:
+ template<
+ class B
+ // Can't use TVARIADIC_COMMA here.
+ BOOST_PP_COMMA_IF(BOOST_CONTRACT_DETAIL_TVARIADIC)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(I)
+ >
+ void call(
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(I)) {
+ O::template BOOST_CONTRACT_DETAIL_NAME1(call_base)<B>(
+ me_.v_,
+ me_.object()
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(
+ BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, I, me_.args_)
+ );
+ }
+
+ cond_subcontracting& me_;
+ };
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ VR& r_;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ boost::contract::virtual_* v_;
+ bool base_call_;
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, Args, &, args_)
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/config.hpp b/boost/contract/detail/config.hpp
new file mode 100644
index 0000000000..1bd106e6d0
--- /dev/null
+++ b/boost/contract/detail/config.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_CONFIG_HPP_
+#define BOOST_CONTRACT_DETAIL_CONFIG_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
+
+#include <boost/preprocessor/cat.hpp>
+
+// Turn off BOOST_ASSERT(...) in lib's implementation (always on by default).
+// BOOST_CONTRACT_DETAIL_NDEBUG
+
+#ifndef BOOST_CONTRACT_DETAIL_NAME_INFIX
+ // Do not use underscore "_" to avoid generating reserved names with "__".
+ #define BOOST_CONTRACT_DETAIL_NAME_INFIX X
+#endif
+
+#ifndef BOOST_CONTRACT_DETAIL_NAME_PREFIX
+ #define BOOST_CONTRACT_DETAIL_NAME_PREFIX \
+ BOOST_PP_CAT(boost_contract_detail, BOOST_CONTRACT_DETAIL_NAME_INFIX)
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/debug.hpp b/boost/contract/detail/debug.hpp
new file mode 100644
index 0000000000..9fa580a5f8
--- /dev/null
+++ b/boost/contract/detail/debug.hpp
@@ -0,0 +1,20 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_DEBUG_HPP_
+#define BOOST_CONTRACT_DETAIL_DEBUG_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
+
+// Usually, never #defined (so "debug" assertions always in code).
+#ifdef BOOST_CONTRACT_DETAIL_NDEBUG
+ #define BOOST_CONTRACT_DETAIL_DEBUG(cond) /* nothing */
+#else
+ #include <boost/assert.hpp>
+ // Extra parenthesis around BOOST_ASSERT to be safe because its is a macro.
+ #define BOOST_CONTRACT_DETAIL_DEBUG(cond) (BOOST_ASSERT(cond))
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/decl.hpp b/boost/contract/detail/decl.hpp
new file mode 100644
index 0000000000..aa84e2e16d
--- /dev/null
+++ b/boost/contract/detail/decl.hpp
@@ -0,0 +1,129 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_DECL_HPP_
+#define BOOST_CONTRACT_DETAIL_DECL_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
+
+// Cannot include core/*.hpp other than config.hpp here (avoid circular incl).
+#include <boost/contract/detail/tvariadic.hpp>
+#if !BOOST_CONTRACT_DETAIL_TVARIADIC
+ #include <boost/contract/core/config.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/tuple/elem.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+#endif
+#include <boost/preprocessor/control/expr_iif.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+
+/* PUBLIC */
+
+#define BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
+ arity, is_friend, has_result, \
+ O, VR, F, C, Args, \
+ v, r, f, obj, args \
+) \
+ template< \
+ class O \
+ BOOST_PP_COMMA_IF(has_result) \
+ BOOST_PP_EXPR_IIF(has_result, typename VR) \
+ , typename F \
+ , class C \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, Args) \
+ > \
+ BOOST_PP_EXPR_IIF(is_friend, friend) \
+ boost::contract::specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_result, VR)> \
+ /* no boost::contract:: here for friends (otherwise need fwd decl) */ \
+ public_function( \
+ boost::contract::virtual_* v \
+ BOOST_PP_COMMA_IF(has_result) \
+ BOOST_PP_EXPR_IIF(has_result, VR& r) \
+ , F f \
+ , C* obj \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, Args, &, args) \
+ )
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
+ O, VR, F, C, Args, \
+ v, r, f, obj, args \
+ ) \
+ BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
+ ~, /* is_friend = */ 1, /* has_result = */ 0, \
+ O, VR, F, C, Args, v, r, f, obj, args \
+ ); \
+ BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
+ ~, /* is_friend = */ 1, /* has_result = */ 1, \
+ O, VR, F, C, Args, v, r, f, obj, args \
+ );
+#else
+ /* PRIVATE */
+ #define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_( \
+ z, n, result_O_R_F_C_Args_v_r_f_obj_args) \
+ BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
+ /* arity = */ n, \
+ /* is_friend = */ 1, \
+ BOOST_PP_TUPLE_ELEM(11, 0, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 1, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 2, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 3, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 4, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 5, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 6, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 7, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 8, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 9, result_O_R_F_C_Args_v_r_f_obj_args), \
+ BOOST_PP_TUPLE_ELEM(11, 10, result_O_R_F_C_Args_v_r_f_obj_args) \
+ );
+
+ /* PUBLIC */
+ #define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
+ O, VR, F, C, Args, \
+ v, r, f, obj, args \
+ ) \
+ BOOST_PP_REPEAT_ ## z( \
+ BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
+ BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
+ (/* has_result = */ 0, O, VR, F, C, Args, v, r, f, obj, args) \
+ ) \
+ BOOST_PP_REPEAT_ ## z( \
+ BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
+ BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
+ (/* has_result = */ 1, O, VR, F, C, Args, v, r, f, obj, args) \
+ )
+#endif
+
+#define BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z( \
+ z, is_friend, O, VR, F, C, Args) \
+ template< \
+ class O, typename VR, typename F, class C \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, \
+ BOOST_CONTRACT_MAX_ARGS, Args) \
+ > \
+ BOOST_PP_IIF(is_friend, \
+ friend class boost::contract::detail:: \
+ , \
+ class \
+ ) \
+ cond_subcontracting
+
+/* CODE */
+
+namespace boost {
+ namespace contract {
+ class virtual_;
+
+ template<typename VR = void>
+ class specify_precondition_old_postcondition_except;
+ }
+}
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/declspec.hpp b/boost/contract/detail/declspec.hpp
new file mode 100644
index 0000000000..a1bfb5ceda
--- /dev/null
+++ b/boost/contract/detail/declspec.hpp
@@ -0,0 +1,51 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_DECLSPEC_HPP_
+#define BOOST_CONTRACT_DETAIL_DECLSPEC_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: Indirectly included by contract_macro.hpp so trivial headers only.
+#include <boost/contract/core/config.hpp> // No compile-time overhead.
+#include <boost/config.hpp>
+
+/* 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. However, this library can be
+// safely compiled and used as a static or header-only library only when it is
+// being used by a single program unit (e.g., a single program with only
+// statically linked libraries that check contracts).
+
+#ifdef BOOST_CONTRACT_DYN_LINK
+ #ifdef BOOST_CONTRACT_SOURCE
+ #define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_EXPORT
+ #else
+ #define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_IMPORT
+ #endif
+#else
+ #define BOOST_CONTRACT_DETAIL_DECLSPEC /* nothing */
+#endif
+
+#ifdef BOOST_CONTRACT_HEADER_ONLY
+ #define BOOST_CONTRACT_DETAIL_DECLINLINE inline
+#else
+ #define BOOST_CONTRACT_DETAIL_DECLINLINE /* nothing */
+
+ // Automatically link this lib to correct build variant (for MSVC, etc.).
+ #if !defined(BOOST_ALL_NO_LIB) && \
+ !defined(BOOST_CONTRACT_NO_LIB) && \
+ !defined(BOOST_CONTRACT_SOURCE)
+ #define BOOST_LIB_NAME boost_contract // This lib (static or shared).
+ #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTRACT_DYN_LINK)
+ #define BOOST_DYN_LINK // This lib as shared.
+ #endif
+ #include <boost/config/auto_link.hpp> // Also #undef BOOST_LIB_NAME.
+ #endif
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/inlined.hpp b/boost/contract/detail/inlined.hpp
new file mode 100644
index 0000000000..06c7167f10
--- /dev/null
+++ b/boost/contract/detail/inlined.hpp
@@ -0,0 +1,15 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_INLINED_HPP_
+#define BOOST_CONTRACT_DETAIL_INLINED_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
+
+#include <boost/contract/detail/inlined/old.hpp>
+#include <boost/contract/detail/inlined/core/exception.hpp>
+#include <boost/contract/detail/inlined/detail/checking.hpp>
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/inlined/core/exception.hpp b/boost/contract/detail/inlined/core/exception.hpp
new file mode 100644
index 0000000000..8c3eb3ff95
--- /dev/null
+++ b/boost/contract/detail/inlined/core/exception.hpp
@@ -0,0 +1,502 @@
+
+#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
+
diff --git a/boost/contract/detail/inlined/detail/checking.hpp b/boost/contract/detail/inlined/detail/checking.hpp
new file mode 100644
index 0000000000..c0557af48b
--- /dev/null
+++ b/boost/contract/detail/inlined/detail/checking.hpp
@@ -0,0 +1,49 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_INLINED_DETAIL_CHECKING_HPP_
+#define BOOST_CONTRACT_DETAIL_INLINED_DETAIL_CHECKING_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/detail/checking.hpp>
+#include <boost/contract/detail/declspec.hpp>
+#include <boost/thread/lock_guard.hpp>
+
+namespace boost { namespace contract { namespace detail {
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+void checking::init_unlocked() { flag::ref() = true; }
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+void checking::init_locked() {
+ boost::lock_guard<boost::mutex> lock(mutex::ref());
+ init_unlocked();
+}
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+void checking::done_unlocked() { flag::ref() = false; }
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+void checking::done_locked() {
+ boost::lock_guard<boost::mutex> lock(mutex::ref());
+ done_unlocked();
+}
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+bool checking::already_unlocked() { return flag::ref(); }
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+bool checking::already_locked() {
+ boost::lock_guard<boost::mutex> lock(mutex::ref());
+ return already_unlocked();
+}
+
+} } } // namespace
+
+#endif
+
diff --git a/boost/contract/detail/inlined/old.hpp b/boost/contract/detail/inlined/old.hpp
new file mode 100644
index 0000000000..aaa2fe7826
--- /dev/null
+++ b/boost/contract/detail/inlined/old.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_INLINED_OLD_HPP_
+#define BOOST_CONTRACT_DETAIL_INLINED_OLD_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/old.hpp>
+#include <boost/contract/detail/declspec.hpp>
+
+namespace boost { namespace contract {
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+old_value null_old() { return old_value(); }
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+old_pointer make_old(old_value const& old) {
+ return old_pointer(0, old);
+}
+
+BOOST_CONTRACT_DETAIL_DECLINLINE
+old_pointer make_old(virtual_* v, old_value const& old) {
+ return old_pointer(v, old);
+}
+
+} } // namespacd
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/name.hpp b/boost/contract/detail/name.hpp
new file mode 100644
index 0000000000..5327357e61
--- /dev/null
+++ b/boost/contract/detail/name.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_NAME_HPP_
+#define BOOST_CONTRACT_DETAIL_NAME_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
+
+#include <boost/contract/detail/config.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+/* PUBLIC */
+
+// NOTE: Explicitly list number of names to concatenate using ..._NAME-n
+// (instead of using ..._SEQ_CAT or similar) for optimal speed and reentrancy.
+
+#define BOOST_CONTRACT_DETAIL_NAME1(name1) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_PREFIX, name1)
+
+#define BOOST_CONTRACT_DETAIL_NAME2(name1, name2) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_PREFIX, BOOST_PP_CAT(name1, \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_NAME_INFIX, name2)))
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/none.hpp b/boost/contract/detail/none.hpp
new file mode 100644
index 0000000000..afbd3024e8
--- /dev/null
+++ b/boost/contract/detail/none.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_NONE_HPP_
+#define BOOST_CONTRACT_DETAIL_NONE_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
+
+namespace boost { namespace contract { namespace detail {
+
+// Tag for "no type".
+struct none {
+ // Some lib code use this to avoid unused local var warnings on #if, etc.
+ static none& value() {
+ static none none_value;
+ return none_value;
+ }
+};
+
+// Transform `void` to `none` type (for convenience, instead of using MPL).
+template<typename T> struct none_if_void { typedef T type; };
+template<> struct none_if_void<void> { typedef none type; };
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/noop.hpp b/boost/contract/detail/noop.hpp
new file mode 100644
index 0000000000..f3beabe246
--- /dev/null
+++ b/boost/contract/detail/noop.hpp
@@ -0,0 +1,19 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_NOOP_HPP_
+#define BOOST_CONTRACT_DETAIL_NOOP_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
+
+// Following must be expressions, not statements (as used with if.., etc.).
+
+#define BOOST_CONTRACT_DETAIL_NOOP ((void)0)
+
+// Following always compiles but never evaluates cond (so check correct syntax).
+#define BOOST_CONTRACT_DETAIL_NOEVAL(cond) \
+ (true || (cond) ? BOOST_CONTRACT_DETAIL_NOOP : BOOST_CONTRACT_DETAIL_NOOP)
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operation/constructor.hpp b/boost/contract/detail/operation/constructor.hpp
new file mode 100644
index 0000000000..ce4d2de30c
--- /dev/null
+++ b/boost/contract/detail/operation/constructor.hpp
@@ -0,0 +1,95 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_CONSTRUCTOR_HPP_
+#define BOOST_CONTRACT_DETAIL_CONSTRUCTOR_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_inv.hpp>
+#include <boost/contract/detail/none.hpp>
+#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS))
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/config.hpp>
+ #include <exception>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+// Ctor subcontracting impl via C++ obj construction mechanism.
+template<class C> // Non-copyable base.
+class constructor : public cond_inv</* VR = */ none, C> {
+public:
+ explicit constructor(C* obj) : cond_inv</* VR = */ none, C>(
+ boost::contract::from_constructor, obj) {}
+
+private:
+ #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_OLDS)
+ void init() /* override */ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ checking k;
+ #endif
+ this->check_entry_static_inv();
+ // No object before ctor body so check only static inv at
+ // entry. Ctor pre checked by constructor_precondition.
+ }
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_old();
+ #endif
+ }
+ #endif
+
+public:
+ #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ~constructor() BOOST_NOEXCEPT_IF(false) {
+ this->assert_initialized();
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ checking k;
+ #endif
+
+ // If ctor body threw, no obj so check only static inv. Otherwise,
+ // obj constructed so check static inv, non-static inv, and post.
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_exit_static_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_exit_all_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_post(none());
+ #endif
+ }
+ }
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operation/destructor.hpp b/boost/contract/detail/operation/destructor.hpp
new file mode 100644
index 0000000000..ea8d8780a1
--- /dev/null
+++ b/boost/contract/detail/operation/destructor.hpp
@@ -0,0 +1,102 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
+#define BOOST_CONTRACT_DETAIL_DESTRUCTOR_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_inv.hpp>
+#include <boost/contract/detail/none.hpp>
+#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS))
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/config.hpp>
+ #include <exception>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+// Dtor subcontracting impl via C++ obj destruction mechanism.
+template<class C> // Non-copyable base.
+class destructor : public cond_inv</* VR = */ none, C> {
+public:
+ explicit destructor(C* obj) : cond_inv</* VR = */ none, C>(
+ boost::contract::from_destructor, obj) {}
+
+private:
+ #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_OLDS)
+ void init() /* override */ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ checking k;
+ #endif
+ // Obj exists (before dtor body), check static and non- inv.
+ this->check_entry_all_inv();
+ // Dtor cannot have pre because it has no parameters.
+ }
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_old();
+ #endif
+ }
+ #endif
+
+public:
+ #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ~destructor() BOOST_NOEXCEPT_IF(false) {
+ this->assert_initialized();
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ checking k;
+ #endif
+
+ // If dtor body threw, obj still exists so check subcontracted
+ // static and non- inv (but no post because of throw). Otherwise,
+ // obj destructed so check static inv and post (even if there is no
+ // obj after dtor body, this library allows dtor post, for example
+ // to check static members for an instance counter class).
+ // NOTE: In theory C++ destructors should not throw, but the
+ // language allows for that (even if in C++11 dtors declarations are
+ // implicitly noexcept(true) unless specified otherwise) so this
+ // library must handle such a case.
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_exit_all_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_exit_static_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_post(none());
+ #endif
+ }
+ }
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operation/function.hpp b/boost/contract/detail/operation/function.hpp
new file mode 100644
index 0000000000..db0503c33b
--- /dev/null
+++ b/boost/contract/detail/operation/function.hpp
@@ -0,0 +1,82 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_FUNCTION_HPP_
+#define BOOST_CONTRACT_DETAIL_FUNCTION_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_post.hpp>
+#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS))
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/config.hpp>
+ #include <exception>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+// Used for free function, private and protected member functions.
+class function : public cond_post</* VR = */ none> { // Non-copyable base.
+public:
+ explicit function() : cond_post</* VR = */ none>(
+ boost::contract::from_function) {}
+
+private:
+ #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_OLDS)
+ void init() /* override */ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ {
+ #if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && \
+ !defined( \
+ BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION)
+ checking k;
+ #endif
+ this->check_pre();
+ }
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_old();
+ #endif
+ }
+ #endif
+
+public:
+ #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ~function() BOOST_NOEXCEPT_IF(false) {
+ this->assert_initialized();
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ checking k;
+ #endif
+
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_post(none());
+ #endif
+ }
+ }
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operation/public_function.hpp b/boost/contract/detail/operation/public_function.hpp
new file mode 100644
index 0000000000..6392e4ddbe
--- /dev/null
+++ b/boost/contract/detail/operation/public_function.hpp
@@ -0,0 +1,161 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PUBLIC_FUNCTION_HPP_
+#define BOOST_CONTRACT_DETAIL_PUBLIC_FUNCTION_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
+
+#include <boost/contract/core/virtual.hpp>
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_subcontracting.hpp>
+#include <boost/contract/detail/tvariadic.hpp>
+#include <boost/contract/core/virtual.hpp>
+#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS))
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/config.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <exception>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+template<
+ class O, typename VR, typename F, class C
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
+>
+class public_function : // Non-copyable base.
+ public cond_subcontracting<
+ O, VR, F, C
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
+ >
+{
+public:
+ explicit public_function(
+ boost::contract::virtual_* v, C* obj, VR& r
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, Args, &, args)
+ ) :
+ cond_subcontracting<
+ O, VR, F, C
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, Args)
+ >(
+ boost::contract::from_function, v, obj, r
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
+ BOOST_CONTRACT_MAX_ARGS, args)
+ )
+ {}
+
+private:
+ #if !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ void init() /* override */ {
+ #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ this->init_subcontracted_old();
+ #endif
+ if(!this->base_call()) {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ #endif
+ { // Acquire checking guard.
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ checking k;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ this->check_subcontracted_entry_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ #ifndef \
+ BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
+ this->check_subcontracted_pre();
+ } // Release checking guard (after pre check).
+ #else
+ } // Release checking guard (before pre check).
+ this->check_subcontracted_pre();
+ #endif
+ #else
+ } // Release checking guard.
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_subcontracted_old();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ this->check_subcontracted_entry_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ this->check_subcontracted_pre();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_subcontracted_old();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_subcontracted_exit_inv();
+ #endif
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_subcontracted_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_subcontracted_post();
+ #endif
+ }
+ }
+ }
+ #endif
+
+public:
+ #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ~public_function() BOOST_NOEXCEPT_IF(false) {
+ this->assert_initialized();
+ if(!this->base_call()) {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ checking k;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_subcontracted_exit_inv();
+ #endif
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_subcontracted_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_subcontracted_post();
+ #endif
+ }
+ }
+ }
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operation/static_public_function.hpp b/boost/contract/detail/operation/static_public_function.hpp
new file mode 100644
index 0000000000..d49fcd091d
--- /dev/null
+++ b/boost/contract/detail/operation/static_public_function.hpp
@@ -0,0 +1,103 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_HPP_
+#define BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_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
+
+#include <boost/contract/core/exception.hpp>
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/condition/cond_inv.hpp>
+#include <boost/contract/detail/none.hpp>
+#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS))
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/config.hpp>
+ #include <exception>
+#endif
+
+namespace boost { namespace contract { namespace detail {
+
+// No subcontracting because static so no obj and no substitution principle.
+template<class C> // Non-copyable base.
+class static_public_function : public cond_inv</* VR = */ none, C> {
+public:
+ explicit static_public_function() : cond_inv</* VR = */ none, C>(
+ boost::contract::from_function, /* obj = */ 0) {}
+
+private:
+ #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_OLDS)
+ void init() /* override */ {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ #endif
+ #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS)
+ { // Acquire checking guard.
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ checking k;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ this->check_entry_static_inv();
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ #ifndef \
+ BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
+ this->check_pre();
+ } // Release checking guard (after pre check).
+ #else
+ } // Release checking guard (before pre check).
+ this->check_pre();
+ #endif
+ #else
+ } // Release checking guard
+ #endif
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ this->copy_old();
+ #endif
+ }
+ #endif
+
+public:
+ #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ~static_public_function() BOOST_NOEXCEPT_IF(false) {
+ this->assert_initialized();
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(checking::already()) return;
+ checking k;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ this->check_exit_static_inv();
+ #endif
+ if(std::uncaught_exception()) {
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ this->check_except();
+ #endif
+ } else {
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ this->check_post(none());
+ #endif
+ }
+ }
+ #endif
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/operator_safe_bool.hpp b/boost/contract/detail/operator_safe_bool.hpp
new file mode 100644
index 0000000000..65edc32dd8
--- /dev/null
+++ b/boost/contract/detail/operator_safe_bool.hpp
@@ -0,0 +1,73 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL_HPP_
+#define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL_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
+
+#include <boost/contract/detail/name.hpp>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+// NOTE: This code is inspired by <boost/shared_ptr/detail/operator_bool.hpp>.
+
+/* PRIVATE */
+
+// operator! is redundant, but some compilers need it.
+#define BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr) \
+ bool operator!() const BOOST_NOEXCEPT { return !(bool_expr); }
+
+/* PUBLIC */
+
+#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && \
+ !defined(BOOST_NO_CXX11_NULLPTR)
+ #define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
+ explicit operator bool() const BOOST_NOEXCEPT { return (bool_expr); } \
+ BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
+#elif (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || \
+ defined(__CINT__)
+ #define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
+ operator bool() const BOOST_NOEXCEPT { return (bool_expr); } \
+ BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
+#elif defined(_MANAGED)
+ #define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
+ static void BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func)( \
+ this_type***) {} \
+ typedef void (*BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type))( \
+ this_type***); \
+ operator BOOST_CONTRACT_DETAIL_NANE(operator_safe_bool_type)() \
+ const BOOST_NOEXCEPT { \
+ return (bool_expr) ? \
+ &BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func) : 0; \
+ } \
+ BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
+#elif (defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200)) || \
+ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304)) || \
+ (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590))
+ #define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
+ void BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func)() const {} \
+ typedef void (this_type::*BOOST_CONTRACT_DETAIL_NAME1( \
+ operator_safe_bool_type))() const; \
+ operator BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type)() \
+ const BOOST_NOEXCEPT { \
+ return (bool_expr) ? &this_type:: \
+ BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_func) : 0; \
+ } \
+ BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
+#else
+ #define BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(this_type, bool_expr) \
+ void* BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_data); \
+ typedef void* this_type::*BOOST_CONTRACT_DETAIL_NAME1( \
+ operator_safe_bool_type);\
+ operator BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_type)() \
+ const BOOST_NOEXCEPT { \
+ return (bool_expr) ? &this_type:: \
+ BOOST_CONTRACT_DETAIL_NAME1(operator_safe_bool_data) : 0; \
+ } \
+ BOOST_CONTRACT_OPERATOR_SAFE_BOOL_NOT_(bool_expr)
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/preprocessor/keyword/private.hpp b/boost/contract/detail/preprocessor/keyword/private.hpp
new file mode 100644
index 0000000000..2fc0d853f4
--- /dev/null
+++ b/boost/contract/detail/preprocessor/keyword/private.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_HPP_
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_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
+
+#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+/* PRIVATE */
+
+// Must expand to a single comma `,` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_COMMAprivate ,
+
+// Must expand to empty `` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_EMPTYprivate
+
+/* PUBLIC */
+
+// Precondition: tokens must start with a token concatenable to a macro name
+// (e.g., a literal or integral token).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(tokens) \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_COMMA, tokens)
+
+// Precondition: tokens must start with `private` (this can be
+// checked with `..._IS_PRIVATE` macro above).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PRIVATE(tokens) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PRIVATE_CAT_TO_EMPTY, tokens)
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/preprocessor/keyword/protected.hpp b/boost/contract/detail/preprocessor/keyword/protected.hpp
new file mode 100644
index 0000000000..e9ac94e78c
--- /dev/null
+++ b/boost/contract/detail/preprocessor/keyword/protected.hpp
@@ -0,0 +1,36 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_HPP_
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_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
+
+#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+/* PRIVATE */
+
+// Must expand to a single comma `,` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_COMMAprotected ,
+
+// Must expand to empty `` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_EMPTYprotected
+
+/* PUBLIC */
+
+// Precondition: tokens must start with a token concatenable to a macro name
+// (e.g., a literal or integral token).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(tokens) \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_COMMA, tokens)
+
+// Precondition: tokens must start with `protected` (this can be
+// checked with `..._IS_PROTECTED` macro above).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PROTECTED(tokens) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PROTECTED_CAT_TO_EMPTY, \
+ tokens)
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/preprocessor/keyword/public.hpp b/boost/contract/detail/preprocessor/keyword/public.hpp
new file mode 100644
index 0000000000..b5e7994610
--- /dev/null
+++ b/boost/contract/detail/preprocessor/keyword/public.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_HPP_
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_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
+
+#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+/* PRIVATE */
+
+// Must expand to a single comma `,` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_COMMApublic ,
+
+// Must expand to empty `` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_EMPTYpublic
+
+/* PUBLIC */
+
+// Precondition: tokens must start with a token concatenable to a macro name
+// (e.g., a literal or integral token).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(tokens) \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_COMMA, tokens)
+
+// Precondition: tokens must start with `public` (this can be
+// checked with `..._IS_PUBLIC` macro above).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(tokens) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_PUBLIC_CAT_TO_EMPTY, tokens)
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/preprocessor/keyword/utility/is.hpp b/boost/contract/detail/preprocessor/keyword/utility/is.hpp
new file mode 100644
index 0000000000..d786033544
--- /dev/null
+++ b/boost/contract/detail/preprocessor/keyword/utility/is.hpp
@@ -0,0 +1,30 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_HPP_
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_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
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/variadic/size.hpp>
+
+/* PRIVATE */
+
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_1 0
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_2 1
+
+/* PUBLIC */
+
+// Precondition: A macro named `cat_to_comma_prefix ## token-to-check` must be
+// #defined to expand to `,`.
+// Precondition: tokens must start with a token concatenable to a macro name
+// (e.g., a literal or integral token).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
+ cat_to_comma_prefix, tokens) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS_, \
+ BOOST_PP_VARIADIC_SIZE(BOOST_PP_CAT(cat_to_comma_prefix, tokens)))
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/preprocessor/keyword/virtual.hpp b/boost/contract/detail/preprocessor/keyword/virtual.hpp
new file mode 100644
index 0000000000..2acfaa1de3
--- /dev/null
+++ b/boost/contract/detail/preprocessor/keyword/virtual.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_HPP_
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_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
+
+#include <boost/contract/detail/preprocessor/keyword/utility/is.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+/* PRIVATE */
+
+// Must expand to a single comma `,` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_COMMAvirtual ,
+
+// Must expand to empty `` (not local macros, do not #undefine).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_EMPTYvirtual
+
+/* PUBLIC */
+
+// Precondition: tokens must start with a token concatenable to a macro name
+// (e.g., a literal or integral token).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(tokens) \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_UTILITY_IS( \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_COMMA, tokens)
+
+// Precondition: tokens must start with `virtual` (this can be
+// checked with `..._IS_VIRTUAL` macro above).
+#define BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL(tokens) \
+ BOOST_PP_CAT(BOOST_CONTRACT_DETAIL_PP_KEYWORD_VIRTUAL_CAT_TO_EMPTY, tokens)
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/static_local_var.hpp b/boost/contract/detail/static_local_var.hpp
new file mode 100644
index 0000000000..53495a089a
--- /dev/null
+++ b/boost/contract/detail/static_local_var.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_STATIC_LOCAL_VAR_HPP_
+#define BOOST_CONTRACT_DETAIL_STATIC_LOCAL_VAR_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
+
+namespace boost { namespace contract { namespace detail {
+
+// This is used to hold the state of this library (already checking assertions,
+// failure handers, mutexes, etc.). Local static variables are used instead of
+// global or class-level static variables to avoid ODR errors when this library
+// is used as header-only.
+
+// Use T's default constructor to init the local var.
+template<typename Tag, typename T>
+struct static_local_var {
+ static T& ref() {
+ static T data;
+ return data;
+ }
+};
+
+// Use `init` param to init local var (Init same as or convertible to T).
+// NOTE: Template specializations could be used to program both this and the
+// template above together but some pre-C++11 compilers give errors (e.g., Clang
+// without -std=c++11), plus the `_init` postfix is more readable at call site.
+template<typename Tag, typename T, typename Init, Init init>
+struct static_local_var_init {
+ static T& ref() {
+ static T data = init;
+ return data;
+ }
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/tvariadic.hpp b/boost/contract/detail/tvariadic.hpp
new file mode 100644
index 0000000000..3172d0972b
--- /dev/null
+++ b/boost/contract/detail/tvariadic.hpp
@@ -0,0 +1,190 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_TVARIADIC_HPP_
+#define BOOST_CONTRACT_DETAIL_TVARIADIC_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
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC 0
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC 1
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #include <tuple>
+
+ /* CODE */
+
+ namespace boost { namespace contract { namespace detail {
+ namespace tvariadic_ {
+ template<int...> struct indexes {};
+
+ template<int N, int... I> struct indexes_of :
+ indexes_of<N - 1, N - 1, I...> {};
+ template<int... I> struct indexes_of<0, I...>
+ { typedef indexes<I...> type; };
+ } } } } // namespace
+
+#else
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/tuple/elem.hpp>
+ #include <boost/preprocessor/punctuation/comma_if.hpp>
+ #include <boost/preprocessor/cat.hpp>
+
+ /* PRIVATE */
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEM_(z, n, tuple) \
+ BOOST_PP_CAT(tuple, n)
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_(z, n, tuplevar_values) \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, tuplevar_values), n)( \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, tuplevar_values), n))
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_(z, n, type_qualifier_name) \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, type_qualifier_name), n) \
+ BOOST_PP_TUPLE_ELEM(3, 1, type_qualifier_name) \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 2, type_qualifier_name), n) \
+ ;
+
+ #define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_(z, n, tokens) \
+ tokens
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_ARG_(z, n, name) \
+ BOOST_PP_CAT(name, n)
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAM_(z, n, type_qualifier_name) \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, type_qualifier_name), n) \
+ BOOST_PP_TUPLE_ELEM(3, 1, type_qualifier_name) \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 2, type_qualifier_name), n)
+
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAM_(z, n, name) \
+ typename BOOST_PP_CAT(name, n)
+#endif
+
+/* PUBLIC */
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ ,
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_PP_COMMA_IF(arity)
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity) /* nothing */
+#else
+ #define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity) \
+ BOOST_PP_COMMA_IF(arity)
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, name) sizeof...(name)
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, name) arity
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, name) \
+ typename... name
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, name) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAM_, \
+ name)
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z( \
+ z, arity, type, qualifier, name) \
+ type qualifier ... name
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z( \
+ z, arity, type, qualifier, name) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAM_, \
+ (type, qualifier, name))
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, name) \
+ name...
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, name) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_ARG_, name)
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity, tokens) \
+ /* nothing */
+#else
+ #define BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity, tokens) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_, \
+ tokens)
+#endif
+
+// Tuple.
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z( \
+ z, arity, type, qualifier, name) \
+ std::tuple<type qualifier ...> name;
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_Z( \
+ z, arity, type, qualifier, name) \
+ BOOST_PP_REPEAT_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_, \
+ (type, qualifier, name))
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(z, \
+ arity, tuple, values) \
+ tuple(values...)
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_Z(z, \
+ arity, tuple, values) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INIT_,\
+ (tuple, values))
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(indexes) \
+ int... indexes
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_TPARAM(indexes) \
+ /* nothing */
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(_indexes) \
+ boost::contract::detail::tvariadic_::indexes<_indexes...>
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_FPARAM(_indexes) \
+ /* nothing */
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(tuple_type) \
+ typename boost::contract::detail::tvariadic_::indexes_of< \
+ sizeof...(tuple_type)>::type()
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_INDEXES_OF(unused) \
+ /* nothing */
+#endif
+
+#if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z( \
+ z, arity, indexes, tuple) \
+ std::get<indexes>(tuple)...
+#else
+ #define BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEMS_Z( \
+ z, arity, indexes, tuple) \
+ BOOST_PP_ENUM_ ## z(arity, BOOST_CONTRACT_DETAIL_TVARIADIC_TUPLE_ELEM_,\
+ tuple)
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/type_traits/member_function_types.hpp b/boost/contract/detail/type_traits/member_function_types.hpp
new file mode 100644
index 0000000000..4966f1db1e
--- /dev/null
+++ b/boost/contract/detail/type_traits/member_function_types.hpp
@@ -0,0 +1,72 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_MEMBER_FUNCTION_TYPES_HPP_
+#define BOOST_CONTRACT_DETAIL_MEMBER_FUNCTION_TYPES_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
+
+#include <boost/contract/detail/none.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/property_tags.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost {
+ namespace contract {
+ class virtual_;
+ }
+}
+
+namespace boost { namespace contract { namespace detail {
+
+template<class C, typename F>
+struct member_function_types {
+ typedef typename boost::function_types::result_type<F>::type result_type;
+
+ // Never include leading class type.
+ typedef typename boost::mpl::pop_front<typename boost::function_types::
+ parameter_types<F>::type>::type argument_types;
+
+ // Always include trailing virtual_* type.
+ typedef typename boost::mpl::if_<boost::is_same<typename boost::
+ mpl::back<argument_types>::type, boost::contract::virtual_*>,
+ boost::mpl::identity<argument_types>
+ ,
+ boost::mpl::push_back<argument_types, boost::contract::virtual_*>
+ >::type::type virtual_argument_types;
+
+ typedef typename boost::mpl::if_<boost::mpl::and_<boost::is_const<C>,
+ boost::is_volatile<C> >,
+ boost::function_types::cv_qualified
+ , typename boost::mpl::if_<boost::is_const<C>,
+ boost::function_types::const_non_volatile
+ , typename boost::mpl::if_<boost::is_volatile<C>,
+ boost::function_types::volatile_non_const
+ ,
+ boost::function_types::null_tag
+ >::type>::type>::type property_tag;
+};
+
+// Also handles none type.
+template<class C>
+struct member_function_types<C, none> {
+ typedef none result_type;
+ typedef none argument_types;
+ typedef none virtual_argument_types;
+ typedef none property_tag;
+};
+
+} } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/type_traits/mirror.hpp b/boost/contract/detail/type_traits/mirror.hpp
new file mode 100644
index 0000000000..ef71451677
--- /dev/null
+++ b/boost/contract/detail/type_traits/mirror.hpp
@@ -0,0 +1,111 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_MIRROR_HPP_
+#define BOOST_CONTRACT_DETAIL_MIRROR_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
+
+#include <boost/contract/detail/name.hpp>
+#include <boost/function_types/member_function_pointer.hpp>
+#include <boost/function_types/function_pointer.hpp>
+#include <boost/function_types/property_tags.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/tuple/rem.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+
+// NOTE: Unfortunately, it is not possible to use Boost.TTI because it not
+// always works on MSVC (e.g., when the mirror meta-function is invoked
+// multiple times, MSVC 2010 gives an internal compiler error). This is a
+// simpler mirror implementation that seems to work better on MSVC.
+
+/* PRIVATE */
+
+#define BOOST_CONTRACT_DETAIL_MIRROR_END_(tparam) \
+ template<typename> \
+ static boost::contract::detail::mirror::no& apply(...); \
+ public: \
+ static bool const value = sizeof(apply<tparam>(0)) == \
+ sizeof(boost::contract::detail::mirror::yes); \
+ typedef boost::mpl::bool_<value> type;
+
+#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_(is_static, \
+ trait, func_name) \
+ template< \
+ typename BOOST_CONTRACT_DETAIL_NAME1(T), \
+ typename BOOST_CONTRACT_DETAIL_NAME1(R), \
+ class BOOST_CONTRACT_DETAIL_NAME1(P), \
+ class BOOST_CONTRACT_DETAIL_NAME1(G) = boost::function_types::null_tag \
+ > \
+ class trait { \
+ template<class BOOST_CONTRACT_DETAIL_NAME1(C)> \
+ static boost::contract::detail::mirror::yes& apply( \
+ boost::contract::detail::mirror::check_function< \
+ typename \
+ BOOST_PP_IIF(is_static, \
+ boost::function_types::function_pointer \
+ , \
+ boost::function_types::member_function_pointer \
+ ) \
+ < \
+ typename boost::mpl::push_front< \
+ BOOST_PP_IIF(is_static, \
+ BOOST_CONTRACT_DETAIL_NAME1(P) \
+ BOOST_PP_TUPLE_EAT(2) \
+ , \
+ BOOST_PP_TUPLE_REM(2) \
+ )( \
+ typename boost::mpl::push_front< \
+ BOOST_CONTRACT_DETAIL_NAME1(P), \
+ BOOST_CONTRACT_DETAIL_NAME1(C) \
+ >::type \
+ ) \
+ , BOOST_CONTRACT_DETAIL_NAME1(R) \
+ >::type, \
+ BOOST_CONTRACT_DETAIL_NAME1(G) \
+ >::type, \
+ &BOOST_CONTRACT_DETAIL_NAME1(C)::func_name \
+ >* \
+ ); \
+ BOOST_CONTRACT_DETAIL_MIRROR_END_( \
+ BOOST_CONTRACT_DETAIL_NAME1(T)) \
+ };
+
+/* PUBLIC */
+
+#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(trait, type_name)\
+ template<typename BOOST_CONTRACT_DETAIL_NAME1(T)> \
+ class trait { \
+ template<class BOOST_CONTRACT_DETAIL_NAME1(C)> \
+ static boost::contract::detail::mirror::yes& apply( \
+ typename BOOST_CONTRACT_DETAIL_NAME1(C)::type_name*); \
+ BOOST_CONTRACT_DETAIL_MIRROR_END_( \
+ BOOST_CONTRACT_DETAIL_NAME1(T)) \
+ };
+
+#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \
+ trait, func_name) \
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \
+ /* is_static = */ 0, trait, func_name)
+
+#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(trait, \
+ func_name) \
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \
+ /* is_static = */ 1, trait, func_name)
+
+/* CODE */
+
+namespace boost { namespace contract { namespace detail { namespace mirror {
+
+typedef class {} yes;
+typedef yes no[2];
+
+template<typename F, F> class check_function;
+
+} } } } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/detail/type_traits/optional.hpp b/boost/contract/detail/type_traits/optional.hpp
new file mode 100644
index 0000000000..453df2f778
--- /dev/null
+++ b/boost/contract/detail/type_traits/optional.hpp
@@ -0,0 +1,42 @@
+
+#ifndef BOOST_CONTRACT_DETAIL_OPTIONAL_HPP_
+#define BOOST_CONTRACT_DETAIL_OPTIONAL_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
+
+#include <boost/optional.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost { namespace contract { namespace detail {
+
+template<typename T>
+struct is_optional : boost::false_type {};
+template<typename T>
+struct is_optional<boost::optional<T> > : boost::true_type {};
+
+template<typename T>
+struct optional_value_type { typedef T type; };
+template<typename T>
+struct optional_value_type<boost::optional<T> > { typedef T type; };
+
+template<typename T>
+struct remove_value_reference_if_optional { typedef T type; };
+template<typename T>
+struct remove_value_reference_if_optional<boost::optional<T> >
+ { typedef typename boost::remove_reference<T>::type type; };
+
+template<typename T>
+T& optional_get(T& x) { return x; }
+template<typename T>
+T& optional_get(boost::optional<T>& x) { return x.get(); }
+template<typename T>
+T& optional_get(boost::optional<T&>& x) { return x.get(); }
+
+} } } // namespace
+
+#endif // #include guard
+