summaryrefslogtreecommitdiff
path: root/boost/contract
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:12:59 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:12:59 +0900
commitb8cf34c691623e4ec329053cbbf68522a855882d (patch)
tree34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/contract
parent3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff)
downloadboost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz
boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2
boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/contract')
-rw-r--r--boost/contract/assert.hpp136
-rw-r--r--boost/contract/base_types.hpp200
-rw-r--r--boost/contract/call_if.hpp617
-rw-r--r--boost/contract/check.hpp347
-rw-r--r--boost/contract/constructor.hpp108
-rw-r--r--boost/contract/core/access.hpp183
-rw-r--r--boost/contract/core/check_macro.hpp133
-rw-r--r--boost/contract/core/config.hpp797
-rw-r--r--boost/contract/core/constructor_precondition.hpp122
-rw-r--r--boost/contract/core/exception.hpp953
-rw-r--r--boost/contract/core/specify.hpp650
-rw-r--r--boost/contract/core/virtual.hpp161
-rw-r--r--boost/contract/destructor.hpp107
-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
-rw-r--r--boost/contract/function.hpp89
-rw-r--r--boost/contract/old.hpp810
-rw-r--r--boost/contract/override.hpp184
-rw-r--r--boost/contract/public_function.hpp876
52 files changed, 9769 insertions, 0 deletions
diff --git a/boost/contract/assert.hpp b/boost/contract/assert.hpp
new file mode 100644
index 0000000000..e7c0ab34a4
--- /dev/null
+++ b/boost/contract/assert.hpp
@@ -0,0 +1,136 @@
+
+#ifndef BOOST_CONTRACT_ASSERT_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Assert contract conditions.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/noop.hpp>
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Preferred way to assert contract conditions.
+
+ Any exception thrown from within a contract (preconditions, postconditions,
+ exception guarantees, old value copies at body, class invariants, etc.) is
+ interpreted by this library as a contract failure.
+ Therefore, users can program contract assertions manually throwing an
+ exception when an asserted condition is checked to be @c false (this
+ library will then call the appropriate contract failure handler
+ @RefFunc{boost::contract::precondition_failure}, etc.).
+ However, it is preferred to use this macro because it expands to
+ code that throws @RefClass{boost::contract::assertion_failure} with the
+ correct assertion file name (using <c>__FILE__</c>), line number (using
+ <c>__LINE__</c>), and asserted condition code so to produce informative
+ error messages.
+
+ @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
+ and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
+ predefined by this library.
+
+ @see @RefSect{tutorial.preconditions, Preconditions},
+ @RefSect{tutorial.postconditions, Postconditions},
+ @RefSect{tutorial.exception_guarantees, Exceptions Guarantees},
+ @RefSect{tutorial.class_invariants, Class Invariants}
+
+ @param cond Boolean contract condition to check.
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_ASSERT((cond)) will always work.)
+ */
+ // This must be an expression (a trivial one so the compiler can optimize it
+ // away). It cannot an empty code block `{}`, etc. otherwise code like
+ // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
+ #define BOOST_CONTRACT_ASSERT(cond)
+#elif !defined(BOOST_CONTRACT_NO_ALL)
+ #include <boost/contract/detail/assert.hpp>
+ #define BOOST_CONTRACT_ASSERT(cond) \
+ BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */
+#else
+ // This must be an expression (a trivial one so the compiler can optimize it
+ // away). It cannot an empty code block `{}`, etc. otherwise code like
+ // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL.
+ #define BOOST_CONTRACT_ASSERT(cond) \
+ BOOST_CONTRACT_DETAIL_NOOP
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Preferred way to assert contract conditions that are computationally
+ expensive, at least compared to the cost of executing the function body.
+
+ The asserted condition will always be compiled and validated syntactically,
+ but it will not be checked at run-time unless
+ @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default).
+ This macro is defined by code equivalent to:
+
+ @code
+ #ifdef BOOST_CONTRACT_AUDITS
+ #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
+ BOOST_CONTRACT_ASSERT(cond)
+ #else
+ #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
+ BOOST_CONTRACT_ASSERT(true || cond)
+ #endif
+ @endcode
+
+ @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT},
+ and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels
+ predefined by this library.
+ If there is a need, programmers are free to implement their own assertion
+ levels defining macros similar to the one above.
+
+ @see @RefSect{extras.assertion_levels, Assertion Levels}
+
+ @param cond Boolean contract condition to check.
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.)
+ */
+ #define BOOST_CONTRACT_ASSERT_AUDIT(cond)
+#elif defined(BOOST_CONTRACT_AUDITS)
+ #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
+ BOOST_CONTRACT_ASSERT(cond)
+#else
+ #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \
+ BOOST_CONTRACT_DETAIL_NOEVAL(cond)
+#endif
+
+/**
+Preferred way to assert contract conditions that are computationally
+prohibitive, at least compared to the cost of executing the function body.
+
+The asserted condition will always be compiled and validated syntactically, but
+it will never be checked at run-time.
+This macro is defined by code equivalent to:
+
+@code
+ #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
+ BOOST_CONTRACT_ASSERT(true || cond)
+@endcode
+
+@RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and
+@RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined
+by this library.
+If there is a need, programmers are free to implement their own assertion levels
+defining macros similar to the one above.
+
+@see @RefSect{extras.assertion_levels, Assertion Levels}
+
+@param cond Boolean contract condition to check.
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.)
+*/
+#define BOOST_CONTRACT_ASSERT_AXIOM(cond) \
+ BOOST_CONTRACT_DETAIL_NOEVAL(cond)
+
+#endif // #include guard
+
diff --git a/boost/contract/base_types.hpp b/boost/contract/base_types.hpp
new file mode 100644
index 0000000000..2ab47d6e8b
--- /dev/null
+++ b/boost/contract/base_types.hpp
@@ -0,0 +1,200 @@
+
+#ifndef BOOST_CONTRACT_BASE_TYPES_HPP_
+#define BOOST_CONTRACT_BASE_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
+
+/** @file
+Specify inheritance form base classes (for subcontracting).
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#include <boost/preprocessor/config/config.hpp>
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+
+/**
+Used to program a @c typedef listing the bases of a derived class.
+
+In order to support subcontracting, a derived class that specifies contracts for
+one or more overriding public function must declare a @c typedef named
+@c base_types (or @RefMacro{BOOST_CONTRACT_BASES_TYPEDEF}) using this macro.
+
+ @code
+ class u :
+ #define BASES public b, protected virtual w1, private w2
+ BASES
+ {
+ friend class boost::contract:access;
+
+ typedef BOOST_CONTRACT_BASES(BASES) base_types;
+ #undef BASES
+
+ ...
+ };
+ @endcode
+
+This @c typedef must be @c public if @RefClass{boost::contract::access} is not
+used.
+
+@see @RefSect{tutorial.base_classes__subcontracting_, Base Classes}
+
+@param ... Comma separated list of base classes.
+ Each base must explicitly specify its access specifier @c public,
+ @c protected, or @c private, and also @c virtual when present
+ (this not always required in C++ instead).
+ There is a limit of about 20 maximum bases that can be listed
+ (because of similar limits in Boost.MPL internally used by this
+ library).
+ This is a variadic macro parameter, on compilers that do not support
+ variadic macros, the @c typedef for base classes can be programmed
+ manually without using this macro.
+*/
+#define BOOST_CONTRACT_BASE_TYPES(...)
+
+#elif !BOOST_PP_VARIADICS
+
+#define BOOST_CONTRACT_BASE_TYPES \
+BOOST_CONTRACT_ERROR_macro_BASE_TYPES_requires_variadic_macros_otherwise_manually_program_base_types
+
+#elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
+
+#include <boost/mpl/vector.hpp>
+#include <boost/contract/detail/preprocessor/keyword/virtual.hpp>
+#include <boost/contract/detail/preprocessor/keyword/public.hpp>
+#include <boost/contract/detail/preprocessor/keyword/protected.hpp>
+#include <boost/contract/detail/preprocessor/keyword/private.hpp>
+#include <boost/preprocessor/variadic/to_seq.hpp>
+#include <boost/preprocessor/seq/fold_left.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/seq/push_back.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/seq/seq.hpp> // For HEAD, TAIL, etc.
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/preprocessor/tuple/rem.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/facilities/expand.hpp>
+
+/* PRIVATE */
+
+#define BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
+ BOOST_PP_EXPAND( \
+ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(base), \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL \
+ , \
+ BOOST_PP_TUPLE_REM(1) \
+ )(base) \
+ )
+
+#define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_(is_public, types_nilseq, base) \
+ ( \
+ is_public, \
+ BOOST_PP_IIF(is_public, \
+ BOOST_PP_SEQ_PUSH_BACK \
+ , \
+ types_nilseq BOOST_PP_TUPLE_EAT(2) \
+ )(types_nilseq, base) \
+ )
+
+#define BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_(is_public, types_nilseq, \
+ base) \
+ (0, types_nilseq)
+
+// Precondition: base = `public [virtual] ...`.
+#define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_(is_public, types_nilseq, \
+ base) \
+ ( \
+ 1, \
+ BOOST_PP_SEQ_PUSH_BACK(types_nilseq, \
+ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_( \
+ BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(base)) \
+ ) \
+ )
+
+#define BOOST_CONTRACT_BASE_TYPES_ACCESS_(is_public, types_nilseq, base) \
+ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
+ BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_ \
+ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
+ BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
+ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
+ BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
+ , \
+ BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_ \
+ )))(is_public, types_nilseq, base)
+
+#define BOOST_CONTRACT_BASE_TYPES_(s, public_types, base) \
+ BOOST_CONTRACT_BASE_TYPES_ACCESS_( \
+ BOOST_PP_TUPLE_ELEM(2, 0, public_types), \
+ BOOST_PP_TUPLE_ELEM(2, 1, public_types), \
+ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
+ )
+
+#define BOOST_CONTRACT_BASE_TYPES_RETURN_YES_(types_nilseq) \
+ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(types_nilseq))
+
+#define BOOST_CONTRACT_BASE_TYPES_RETURN_(types_nilseq) \
+ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(types_nilseq), 1), \
+ BOOST_PP_TUPLE_EAT(1) \
+ , \
+ BOOST_CONTRACT_BASE_TYPES_RETURN_YES_ \
+ )(types_nilseq)
+
+#define BOOST_CONTRACT_BASE_TYPES_OK_(base_tuple, bases_seq) \
+ boost::mpl::vector< \
+ BOOST_CONTRACT_BASE_TYPES_RETURN_(BOOST_PP_TUPLE_ELEM(2, 1, \
+ BOOST_PP_SEQ_FOLD_LEFT( \
+ BOOST_CONTRACT_BASE_TYPES_, \
+ (0, (BOOST_PP_NIL)), \
+ bases_seq \
+ ) \
+ )) \
+ >
+
+#define BOOST_CONTRACT_BASE_TYPES_ERR_(bases_tuple, bases_seq) \
+ BOOST_CONTRACT_ERROR_all_bases_must_explicitly_specify_public_protected_or_private base_tuple
+
+#define BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_(base) \
+ BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
+ 1 \
+ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
+ 1 \
+ , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
+ 1 \
+ , \
+ 0 \
+ )))
+
+// Cannot check that all base types have access specifiers (unless users have to
+// specify bases using pp-seq, because user specified base list can have
+// unwrapped commas between bases but also within a given base type, when base
+// types are templates), but at least check the very first base type explicitly
+// specifies access `[virtual] public | protected | private [virtual] ...`.
+#define BOOST_CONTRACT_BASE_TYPES_CHECK_(bases_tuple, bases_seq) \
+ BOOST_PP_IIF(BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_( \
+ BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(BOOST_PP_SEQ_HEAD( \
+ bases_seq))), \
+ BOOST_CONTRACT_BASE_TYPES_OK_ \
+ , \
+ BOOST_CONTRACT_BASE_TYPES_ERR_ \
+ )(bases_tuple, bases_seq)
+
+/* PUBLIC */
+
+#define BOOST_CONTRACT_BASE_TYPES(...) \
+ BOOST_CONTRACT_BASE_TYPES_CHECK_((__VA_ARGS__), \
+ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
+
+#else
+
+#define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */
+
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/call_if.hpp b/boost/contract/call_if.hpp
new file mode 100644
index 0000000000..7d7586cbfb
--- /dev/null
+++ b/boost/contract/call_if.hpp
@@ -0,0 +1,617 @@
+
+#ifndef BOOST_CONTRACT_CALL_IF_HPP_
+#define BOOST_CONTRACT_CALL_IF_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
+
+/** @file
+Statically disable compilation and execution of functor calls.
+
+@note This facility allows to emulate C++17 <c>if constexpr</c> statements
+ when used together with functor templates (or C++14 generic lambdas).
+*/
+
+#include <boost/contract/detail/none.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/config.hpp>
+
+/* PRIVATE */
+
+/** @cond */
+
+// Boost.ResultOf not always able to deduce lambda result type (on MSVC).
+#ifndef BOOST_NO_CXX11_DECLTYPE
+ #include <boost/utility/declval.hpp>
+ #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \
+ decltype(boost::declval<F>()())
+#else
+ #include <boost/utility/result_of.hpp>
+ #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \
+ typename boost::result_of<F()>::type
+#endif
+
+/** @endcond */
+
+/* CODE */
+
+namespace boost { namespace contract {
+
+/**
+Select compilation and execution of functor template calls using a static
+boolean predicate.
+
+This class template has no members because it is never used directly, it is only
+used via its specializations.
+Usually this class template is instantiated only via the return value of
+@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@tparam Pred Static boolean predicate that selects which functor template
+ call to compile and execute.
+@tparam Then Type of the functor template to call if the static predicate
+ @c Pred is @c true.
+@tparam ThenResult Return type of then-branch functor template call (this is
+ usually automatically deduced by this library so it is never explicitly
+ specified by the user, and that is why it is often marked as
+ @c internal_type in this documentation).
+*/
+template<bool Pred, typename Then, typename ThenResult =
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ boost::contract::detail::none
+ #else
+ internal_type
+ #endif
+>
+struct call_if_statement {}; // Empty so cannot be used (but copyable).
+
+/**
+Template specialization to dispatch between then-branch functor template calls
+that return void and the ones that return non-void.
+
+The base class is a call-if statement so the else and else-if statements can be
+specified if needed.
+Usually this class template is instantiated only via the return value of
+@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
+
+@note The <c>result_of<Then()>::type</c> expression should be evaluated only
+ when the static predicate is already checked to be @c true (because
+ @c Then() is required to compile only in that case).
+ Thus, this template specialization introduces an extra level of
+ indirection necessary for proper lazy evaluation of this result-of
+ expression.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@tparam Then Type of functor template to call when the static predicate is
+ @c true (as it is for this template specialization).
+*/
+template<typename Then>
+struct call_if_statement<true, Then,
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ boost::contract::detail::none
+ #else
+ internal_type
+ #endif
+> :
+ call_if_statement<true, Then,
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)
+ #else
+ typename result_of<Then()>::type
+ #endif
+ >
+{ // Copyable (as its base).
+ /**
+ Construct this object with the then-branch functor template.
+
+ @param f Then-branch nullary functor template.
+ The functor template call @c f() is compiled and called for this
+ template specialization (because the if-statement static
+ predicate is @c true).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the return type of all other functor template
+ calls specified for this call-if object.
+ */
+ explicit call_if_statement(Then f) : call_if_statement<true, Then,
+ BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>(f) {}
+};
+
+/**
+Template specialization to handle static predicates that are @c true for
+then-branch functor template calls that do not return void.
+
+Usually this class template is instantiated only via the return value of
+@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@tparam Then Type of functor template to call when the static predicate is
+ @c true (as it is for this template specialization).
+@tparam ThenResult Non-void return type of the then-branch functor template
+ call.
+*/
+template<typename Then, typename ThenResult>
+struct call_if_statement<true, Then, ThenResult> { // Copyable (as *).
+ /**
+ Construct this object with the then-branch functor template.
+
+ @param f Then-branch nullary functor template.
+ The functor template call @c f() is actually compiled and
+ executed for this template specialization (because the
+ if-statement static predicate is @c true).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the @p ThenResult type.
+ */
+ explicit call_if_statement(Then f) :
+ r_(boost::make_shared<ThenResult>(f())) {}
+
+ /**
+ This implicit type conversion returns a copy of the value returned by the
+ call to the then-branch functor template.
+ */
+ operator ThenResult() const { return *r_; }
+
+ /**
+ Specify the else-branch functor template.
+
+ @param f Else-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the @p ThenResult type.
+
+ @return A copy of the value returned by the call to the then-branch functor
+ template (because the else-branch functor template call is not
+ executed).
+ */
+ template<typename Else>
+ ThenResult else_(Else const& f) const { return *r_; }
+
+ /**
+ Specify an else-if-branch functor template (using a static boolean
+ predicate).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the @p ThenResult type.
+
+ @tparam ElseIfPred Static boolean predicate selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, it will be the return value of the then-branch functor
+ template call for this template specialization (because the
+ if-statement static predicate is @c true).
+ */
+ template<bool ElseIfPred, typename ElseIfThen>
+ call_if_statement<true, Then, ThenResult> else_if_c(ElseIfThen const& f)
+ const { return *this; }
+
+ /**
+ Specify an else-if-branch functor template (using a nullary boolean
+ meta-function).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the @p ThenResult type.
+
+ @tparam ElseIfPred Nullary boolean meta-function selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, it will be the return value of the then-branch functor
+ template call for this template specialization (because the
+ if-statement static predicate is @c true).
+ */
+ template<class ElseIfPred, typename ElseIfThen>
+ call_if_statement<true, Then, ThenResult> else_if(ElseIfThen const& f)
+ const { return *this; }
+
+private:
+ boost::shared_ptr<ThenResult> r_;
+};
+
+/**
+Template specialization to handle static predicates that are @c true for
+then-branch functor template calls that return void.
+
+Usually this class template is instantiated only via the return value of
+@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@tparam Then Type of functor template to call when the static predicate if
+ @c true (as it is for this template specialization).
+*/
+template<typename Then>
+struct call_if_statement<true, Then, void> { // Copyable (no data).
+ /**
+ Construct this object with the then-branch functor template.
+
+ @param f Then-branch nullary functor template.
+ The functor template call @c f() is actually compiled and
+ executed for this template specialization (because the
+ if-statement static predicate is @c true).
+ The return type of @c f() must be @c void for this template
+ specialization (because the then-branch functor template calls
+ return void).
+ */
+ explicit call_if_statement(Then f) { f(); }
+
+ // Cannot provide `operator ThenResult()` here, because ThenResult is void.
+
+ /**
+ Specify the else-branch functor template.
+
+ @param f Else-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be @c void for this template
+ specialization (because the then-branch functor template calls
+ return void).
+ */
+ template<typename Else>
+ void else_(Else const& f) const {}
+
+ /**
+ Specify an else-if-branch functor template (using a static boolean
+ predicate).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be @c void for this template
+ specialization (because the then-branch functor template calls
+ return void).
+
+ @tparam ElseIfPred Static boolean predicate selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, it will return void for this template specialization
+ (because the then-branch functor template calls return void).
+ */
+ template<bool ElseIfPred, typename ElseIfThen>
+ call_if_statement<true, Then, void> else_if_c(ElseIfThen const& f) const {
+ return *this;
+ }
+
+ /**
+ Specify an else-if-branch functor template (using a nullary boolean
+ meta-function).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c true).
+ The return type of @c f() must be @c void for this template
+ specialization (because the then-branch functor template calls
+ return void).
+
+ @tparam ElseIfPred Nullary boolean meta-function selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, it will return void for this template specialization
+ (because the then-branch functor template calls return void).
+ */
+ template<class ElseIfPred, typename ElseIfThen>
+ call_if_statement<true, Then, void> else_if(ElseIfThen const& f) const {
+ return *this;
+ }
+};
+
+/**
+Template specialization to handle static predicates that are @c false.
+
+This template specialization handles all else-branch functor template calls
+(whether they return void or not).
+Usually this class template is instantiated only via the return value of
+@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@tparam Then Type of functor template to call when the static predicate is
+ @c true (never the case for this template specialization).
+*/
+template<typename Then> // Copyable (no data).
+struct call_if_statement<false, Then,
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ boost::contract::detail::none
+ #else
+ internal_type
+ #endif
+> {
+ /**
+ Construct this object with the then-branch functor template.
+
+ @param f Then-branch nullary functor template.
+ The functor template call @c f() is never compiled and executed
+ for this template specialization (because the if-statement
+ static predicate is @c false).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the return type of all other functor template
+ calls specified for this call-if object.
+ */
+ explicit call_if_statement(Then const& f) {}
+
+ // Do not provide `operator result_type()` here, require else_ instead.
+
+ /**
+ Specify the else-branch functor template.
+
+ @note The <c>result_of<Else()>::type</c> expression should be evaluated
+ only when the static predicate is already checked to be @c false
+ (because @c Else() is required to compile only in that case).
+ Thus, this result-of expression is evaluated lazily only in
+ instantiations of this template specialization.
+
+ @param f Else-branch nullary functor template.
+ The functor template call @c f() is actually compiled and
+ executed for this template specialization (because the
+ if-statement static predicate is @c false).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the return type of all other functor template
+ calls specified for this call-if object.
+
+ @return A copy of the value returned by the call to the else-branch functor
+ template @c f().
+ */
+ template<typename Else>
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CALL_IF_RESULT_OF_(Else)
+ #else
+ typename result_of<Else()>::type
+ #endif
+ else_(Else f) const { return f(); }
+
+ /**
+ Specify an else-if-branch functor template (using a static boolean
+ predicate).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is actually compiled and
+ executed if and only if @c ElseIfPred is @c true (because the
+ if-statement static predicate is already @c false for this
+ template specialization).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the return type of all other functor template
+ calls specified for this call-if object.
+
+ @tparam ElseIfPred Static boolean predicate selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, this will be the return value of the functor template
+ call being compiled and executed.
+ */
+ template<bool ElseIfPred, typename ElseIfThen>
+ call_if_statement<ElseIfPred, ElseIfThen> else_if_c(ElseIfThen f) const {
+ return call_if_statement<ElseIfPred, ElseIfThen>(f);
+ }
+
+ /**
+ Specify an else-if-branch functor template (using a nullary boolen
+ meta-function).
+
+ @param f Else-if-branch nullary functor template.
+ The functor template call @c f() is actually compiled and
+ executed if and only if @c ElseIfPred::value is @c true (because
+ the if-statement static predicate is already @c false for this
+ template specialization).
+ The return type of @c f() must be the same as (or implicitly
+ convertible to) the return type of all other functor template
+ calls specified for this call-if object.
+
+ @tparam ElseIfPred Nullary boolean meta-function selecting which functor
+ template call to compile and execute.
+
+ @return A call-if statement so the else statement and additional else-if
+ statements can be specified if needed.
+ Eventually, this will be the return value of the functor template
+ call being compiled and executed.
+ */
+ template<class ElseIfPred, typename ElseIfThen>
+ call_if_statement<ElseIfPred::value, ElseIfThen> else_if(ElseIfThen f)
+ const {
+ return call_if_statement<ElseIfPred::value, ElseIfThen>(f);
+ }
+};
+
+/**
+Select compilation and execution of functor template calls using a static
+boolean predicate.
+
+Create a call-if object with the specified then-branch functor template:
+
+@code
+boost::contract::call_if_c<Pred1>(
+ then_functor_template1
+).template else_if_c<Pred2>( // Optional.
+ then_functor_template2
+) // Optionally, other `else_if_c` or
+... // `else_if`.
+.else_( // Optional for `void` functors,
+ else_functor_template // but required for non `void`.
+)
+@endcode
+
+Optional functor templates for else-if-branches and the else-branch can be
+specified as needed (the else-branch function template is required if @c f
+returns non-void).
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@param f Then-branch nullary functor template.
+ The functor template call @c f() is compiled and executed if and
+ only if @c Pred is @c true.
+ The return type of other functor template calls specified for this
+ call-if statement (else-branch, else-if-branches, etc.) must be the
+ same as (or implicitly convertible to) the return type of
+ then-branch functor call @c f().
+
+@tparam Pred Static boolean predicate selecting which functor template call
+ to compile and execute.
+
+@return A call-if statement so else and else-if statements can be specified if
+ needed.
+ Eventually, this will be the return value of the functor template call
+ being compiled and executed (which can also be @c void).
+*/
+template<bool Pred, typename Then>
+call_if_statement<Pred, Then> call_if_c(Then f) {
+ return call_if_statement<Pred, Then>(f);
+}
+
+/**
+Select compilation and execution of functor template calls using a nullary
+boolean meta-function.
+
+This is equivalent to <c>boost::contract::call_if_c<Pred::value>(f)</c>.
+Create a call-if object with the specified then-branch functor template:
+
+@code
+boost::contract::call_if<Pred1>(
+ then_functor_template1
+).template else_if<Pred2>( // Optional.
+ then_functor_template2
+) // Optionally, other `else_if` or
+... // `else_if_c`.
+.else_( // Optional for `void` functors,
+ else_functor_template // but required for non `void`.
+)
+@endcode
+
+Optional functor templates for else-if-branches and the else-branch can be
+specified as needed (the else-branch functor template is required if @c f
+returns non-void).
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@param f Then-branch nullary functor template.
+ The functor template call @c f() is compiled and executed if and
+ only if @c Pred::value is @c true.
+ The return type of other functor template calls specified for this
+ call-if statement (else-branch, else-if-branches, etc.) must be the
+ same as (or implicitly convertible to) the return type of
+ then-branch functor template call @c f().
+
+@tparam Pred Nullary boolean meta-function selecting which functor template
+ call to compile and execute.
+
+@return A call-if statement so else and else-if statements can be specified if
+ needed.
+ Eventually, this will be the return value of the functor template call
+ being compiled and executed (which can also be @c void).
+*/
+template<class Pred, typename Then>
+call_if_statement<Pred::value, Then> call_if(Then f) {
+ return call_if_statement<Pred::value, Then>(f);
+}
+
+/**
+Select compilation and execution of a boolean functor template condition using a
+static boolean predicate.
+
+Compile and execute the nullary boolean functor template call @c f() if and only
+if the specified static boolean predicate @p Pred is @c true, otherwise
+trivially return @p else_ (@c true by default) at run-time.
+
+A call to <c>boost::contract::condition_if_c<Pred>(f, else_)</c> is logically
+equivalent to
+<c>boost::contract::call_if_c<Pred>(f, [else_] { return else_; })</c> (but
+its internal implementation is optimized and it does not actually use
+@c call_if_c).
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@param f Nullary boolean functor template.
+ The functor template call @c f() is compiled and executed if and
+ only if @c Pred is @c true.
+
+@tparam Pred Static boolean predicate selecting when the functor template
+ call @c f() should be compiled and executed.
+@param else_ Boolean value to return when @c Pred is @c false (instead of
+ compiling and executing the functor template call @c f()).
+
+@return Boolean value returned by @c f() if the static predicate @c Pred is
+ @c true. Otherwise, trivially return @p else_.
+*/
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ template<bool Pred, typename Then>
+ bool condition_if_c(Then f, bool else_ = true);
+#else
+ // NOTE: condition_if is a very simple special case of call_if so it can be
+ // trivially implemented using enable_if instead of call_if as done below.
+
+ template<bool Pred, typename Then>
+ typename boost::enable_if_c<Pred, bool>::type
+ condition_if_c(Then f, bool else_ = true) { return f(); }
+
+ template<bool Pred, typename Then>
+ typename boost::disable_if_c<Pred, bool>::type
+ condition_if_c(Then f, bool else_ = true) { return else_; }
+#endif
+
+/**
+Select compilation and execution of a boolean functor template condition using a
+nullary boolean meta-function.
+
+This is equivalent to
+<c>boost::contract::condition_if_c<Pred::value>(f, else_)</c>.
+Compile and execute the nullary boolean functor template call @c f() if and only
+if the specified nullary boolean meta-function @p Pred is @c true, otherwise
+trivially return @p else_ (@c true by default) at run-time.
+
+@see @RefSect{extras.assertion_requirements__templates_,
+ Assertion Requirements}
+
+@param f Nullary boolean functor template.
+ The functor template call @c f() is compiled and executed if and
+ only if @c Pred::value is @c true.
+@param else_ Boolean value to return when @c Pred::value is @c false (instead
+ of compiling and executing the functor template call @c f()).
+
+@tparam Pred Nullary boolean meta-function selecting when the functor
+ template call @c f() should be compiled and executed.
+
+@return Boolean value returned by @c f() if the static predicate @c Pred is
+ @c true. Otherwise, trivially return @p else_.
+*/
+template<class Pred, typename Then>
+bool condition_if(Then f, bool else_ = true) {
+ return condition_if_c<Pred::value>(f, else_);
+}
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/check.hpp b/boost/contract/check.hpp
new file mode 100644
index 0000000000..e7423ce9a8
--- /dev/null
+++ b/boost/contract/check.hpp
@@ -0,0 +1,347 @@
+
+#ifndef BOOST_CONTRACT_CHECK_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+RAII object that checks contracts.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/check_macro.hpp>
+#include <boost/contract/core/specify.hpp>
+#include <boost/contract/core/exception.hpp> // For set_... (if always in code).
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/condition/cond_base.hpp>
+ #include <boost/contract/detail/auto_ptr.hpp>
+ #include <boost/contract/detail/debug.hpp>
+#endif
+#include <boost/contract/detail/check.hpp>
+#include <boost/config.hpp>
+
+/* PRIVATE */
+
+/** @cond */
+
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) \
+ : cond_(const_cast<contract_type&>(contract).cond_.release()) \
+ { \
+ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
+ cond_->initialize(); \
+ }
+#else
+ #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) {}
+#endif
+
+/** @endcond */
+
+/* CODE */
+
+namespace boost { namespace contract {
+
+/**
+RAII object that checks the contracts.
+
+In general, when this object is constructed it checks class invariants at entry,
+preconditions, and makes old value copies at body.
+When it is destructed, it checks class invariants at exist, postconditions, and
+exception guarantees.
+This object enforces the following (see
+@RefSect{contract_programming_overview, Contract Programming Overview}):
+
+@li Postconditions are checked only if the body does not throw an exception.
+@li Exceptions guarantees are checked only if the body throws an exception.
+@li Constructor entry never checks class invariants.
+@li Destructor exit checks class invariants only if the body throws an
+exception (even if destructors should usually not be programmed to throw
+exceptions in C++).
+@li Static invariants are always checked at entry and exit (and regardless of
+the body throwing exceptions or not).
+
+When used this way, this object is usually constructed and initialized to the
+return value of one of the contract functions
+@RefFunc{boost::contract::function}, @RefFunc{boost::contract::constructor},
+@RefFunc{boost::contract::destructor}, or
+@RefFunc{boost::contract::public_function}.
+In addition, this object can be constructed from a nullary functor that is used
+to program implementation checks.
+
+@see @RefSect{tutorial, Tutorial},
+ @RefSect{advanced.implementation_checks, Implementation Checks}
+*/
+class check { // Copy ctor only (as move via ptr release).
+public:
+ // NOTE: Unfortunately, Apple compilers define a `check(...)` macro that
+ // clashes with the name of this class. In the following code,
+ // BOOST_PREVENT_MACRO_SUBSTITUTION is used to workaround these name
+ // clashes. In user code, `check c = ...` syntax is typically used also
+ // avoiding clashes.
+
+ /**
+ Construct this object for implementation checks.
+
+ This can be used to program checks within implementation code (body, etc.).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param f Nullary functor that asserts implementation checks. @c f() will
+ be called as soon as this object is constructed at the point it
+ is declared within the implementation code (see
+ @RefSect{advanced.implementation_checks,
+ Implementation Checks}).
+ */
+ template<typename F> // Cannot check `if(f) ...` as f can be a lambda.
+ // f must be a valid callable object (not null func ptr, empty ftor, etc.
+ /* implicit */ check
+ /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ F const& f) {
+ BOOST_CONTRACT_DETAIL_CHECK({ f(); })
+ }
+
+ /**
+ Construct this object copying it from the specified one.
+
+ This object will check the contract, the copied-from object will not (i.e.,
+ contract check ownership is transferred from the copied object to the new
+ object being created by this constructor).
+
+ @param other Copied-from object.
+ */
+ check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ check const& other)
+ #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ // Copy ctor moves cond_ pointer to dest.
+ : cond_(const_cast<check&>(other).cond_.release())
+ #endif
+ {}
+
+ /**
+ Construct this object to check the specified contract.
+
+ This checks class invariants at entry (if those apply to the specified
+ contract).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param contract Contract to be checked (usually the return value of
+ @RefFunc{boost::contract::function} or
+ @RefFunc{boost::contract::public_function}).
+
+ @tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that is either a virtual or an
+ overriding public function.
+ Otherwise, this is always @c void.
+ */
+ template<typename VirtualResult>
+ /* implicit */ check
+ /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ specify_precondition_old_postcondition_except<VirtualResult> const&
+ contract
+ )
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CHECK_CTOR_DEF_(
+ specify_precondition_old_postcondition_except<VirtualResult>)
+ #else
+ ;
+ #endif
+
+ /**
+ Construct this object to check the specified contract.
+
+ This checks class invariants at entry and preconditions (if any of those
+ apply to the specified contract).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param contract Contract to be checked (usually the return value of
+ @RefFunc{boost::contract::function},
+ @RefFunc{boost::contract::constructor},
+ @RefFunc{boost::contract::destructor}, or
+ @RefFunc{boost::contract::public_function}).
+
+ @tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that is either a virtual or an
+ overriding public function.
+ Otherwise, this is always @c void.
+ */
+ template<typename VirtualResult>
+ /* implicit */ check
+ /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ specify_old_postcondition_except<VirtualResult> const& contract)
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CHECK_CTOR_DEF_(
+ specify_old_postcondition_except<VirtualResult>)
+ #else
+ ;
+ #endif
+
+ /**
+ Construct this object to check the specified contract.
+
+ This checks class invariants at entry and preconditions then it makes old
+ value copies at body (if any of those apply to the specified contract).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating te
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param contract Contract to be checked (usually the return value of
+ @RefFunc{boost::contract::function},
+ @RefFunc{boost::contract::constructor},
+ @RefFunc{boost::contract::destructor}, or
+ @RefFunc{boost::contract::public_function}).
+
+ @tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that is either a virtual or an
+ overriding public function.
+ Otherwise, this is always @c void.
+ */
+ template<typename VirtualResult>
+ /* implicit */ check
+ /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ specify_postcondition_except<VirtualResult> const& contract)
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CHECK_CTOR_DEF_(
+ specify_postcondition_except<VirtualResult>)
+ #else
+ ;
+ #endif
+
+ /**
+ Construct this object to check the specified contract.
+
+ This checks class invariants at entry and preconditions then it makes old
+ value copies at body, plus the destructor of this object will check
+ postconditions in this case (if any of those apply to the specified
+ contract).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param contract Contract to be checked (usually the return value of
+ @RefFunc{boost::contract::function},
+ @RefFunc{boost::contract::constructor},
+ @RefFunc{boost::contract::destructor}, or
+ @RefFunc{boost::contract::public_function}).
+
+ @tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that is either a virtual or an
+ overriding public function.
+ Otherwise, this is always @c void.
+ */
+ /* implicit */ check
+ /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ specify_except const& contract)
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_except)
+ #else
+ ;
+ #endif
+
+ /**
+ Construct this object to check the specified contract.
+
+ This checks class invariants at entry and preconditions then it makes old
+ value copies at body, plus the destructor of this object will check
+ postconditions and exception guarantees in this case (if any of those apply
+ to the specified contract).
+ This constructor is not declared @c explicit so initializations can use
+ assignment syntax @c =.
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+
+ @param contract Contract to be checked (usually the return value of
+ @RefFunc{boost::contract::function},
+ @RefFunc{boost::contract::constructor},
+ @RefFunc{boost::contract::destructor}, or
+ @RefFunc{boost::contract::public_function}).
+
+ @tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that is either a virtual or an
+ overriding public function.
+ Otherwise, this is always @c void.
+ */
+ /* implicit */ check
+ /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
+ specify_nothing const& contract)
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_nothing)
+ #else
+ ;
+ #endif
+
+ /**
+ Destruct this object.
+
+ This checks class invariants at exit and either postconditions when the
+ enclosing function body did not throw an exception, or exception guarantees
+ when the function body threw an exception (that is if class invariants,
+ postconditions, and exception guarantees respectively apply to the contract
+ parameter specified when constructing this object).
+
+ @b Throws: This can throw in case programmers specify contract failure
+ handlers that throw exceptions instead of terminating the
+ program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ()
+ BOOST_NOEXCEPT_IF(false) /* allow auto_ptr dtor to throw */
+ {}
+
+/** @cond */
+private:
+ check& operator=(check const&); // Cannot copy outside of `check c = ...`.
+
+ #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ boost::contract::detail::auto_ptr<boost::contract::detail::cond_base>
+ cond_;
+ #endif
+/** @endcond */
+};
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/constructor.hpp b/boost/contract/constructor.hpp
new file mode 100644
index 0000000000..9dab3294a5
--- /dev/null
+++ b/boost/contract/constructor.hpp
@@ -0,0 +1,108 @@
+
+#ifndef BOOST_CONTRACT_CONSTRUCTOR_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Program contracts for constructors.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/specify.hpp>
+#include <boost/contract/core/access.hpp>
+#include <boost/contract/core/constructor_precondition.hpp>
+#if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/operation/constructor.hpp>
+#endif
+
+namespace boost { namespace contract {
+
+/**
+Program contracts for constructors.
+
+This is used to specify postconditions, exception guarantees, old value copies
+at body, and check class invariants for constructors (see
+@RefClass{boost::contract::constructor_precondition} to specify preconditions
+for constructors instead):
+
+@code
+class u {
+ friend class boost::contract:access;
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+public:
+ u(...) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::constructor(this)
+ // No `.precondition` (use `constructor_precondition` if needed).
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Constructor body.
+ }
+
+ ...
+};
+@endcode
+
+For optimization, this can be omitted for constructors that do not have
+postconditions and exception guarantees, within classes that have no invariants.
+
+@see @RefSect{tutorial.constructors, Constructors}
+
+@param obj The object @c this from the scope of the enclosing constructor
+ declaring the contract.
+ (Constructors check all class invariants, including static and
+ volatile invariants, see @RefSect{tutorial.class_invariants,
+ Class Invariants} and
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+
+@tparam Class The type of the class containing the constructor declaring the
+ contract.
+ (Usually this template parameter is automatically deduced by C++
+ and it does not need to be explicitly specified by programmers.)
+
+@return The result of this function must be explicitly assigned to a variable of
+ type @RefClass{boost::contract::check} declared locally just before the
+ code of the constructor body (otherwise this library will generate a
+ run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+*/
+template<class Class>
+specify_old_postcondition_except<> constructor(Class* obj) {
+ // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
+ #if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ return specify_old_postcondition_except<>(
+ new boost::contract::detail::constructor<Class>(obj));
+ #else
+ return specify_old_postcondition_except<>();
+ #endif
+}
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/core/access.hpp b/boost/contract/core/access.hpp
new file mode 100644
index 0000000000..ba8334ba0d
--- /dev/null
+++ b/boost/contract/core/access.hpp
@@ -0,0 +1,183 @@
+
+#ifndef BOOST_CONTRACT_ACCESS_HPP_
+#define BOOST_CONTRACT_ACCESS_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
+
+/** @file
+Allow to declare invariants, base types, etc all as private members.
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/decl.hpp>
+ #include <boost/contract/detail/type_traits/mirror.hpp>
+#endif
+#ifndef BOOST_CONTRACT_NO_INVARIANTS
+ #include <boost/contract/detail/debug.hpp>
+ #include <boost/function_types/property_tags.hpp>
+ #include <boost/mpl/vector.hpp>
+#endif
+
+namespace boost { namespace contract {
+
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ class virtual_;
+
+ namespace detail {
+ BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
+ /* is_friend = */ 0, OO, RR, FF, CC, AArgs);
+ }
+#endif
+#ifndef BOOST_CONTRACT_NO_INVARIANTS
+ namespace detail {
+ template<typename RR, class CC>
+ class cond_inv;
+ }
+#endif
+
+/**
+Friend this class to declare invariants and base types as private members.
+
+Declare this class a friend of the user-defined class specifying the contracts
+in order to declare the invariant functions and the base types @c typedef as
+non-public members:
+
+@code
+class u :
+ #define BASES public b, private w
+ BASES
+{
+ friend class boost::contract::access;
+
+ typedef BOOST_CONTRACT_BASES(BASES) base_types; // Private.
+ #undef BASES
+
+ void invariant() const { ... } // Private.
+
+public:
+ ...
+};
+@endcode
+
+In real code, programmers will likely chose to declare this class as friend so
+to fully control public interfaces of their user-defined classes.
+This class is not intended to be directly used by programmers a part from
+declaring it @c friend (and that is why this class does not have any public
+member and it is not copyable).
+
+@warning Not declaring this class friend of user-defined classes will cause
+ compiler errors on some compilers (e.g., MSVC) because the private
+ members needed to check the contracts will not be accessible.
+ On other compilers (e.g., GCC and CLang), the private access will
+ instead fail SFINAE and no compiler error will be reported while
+ invariants and subcontracting will be silently skipped at run-time.
+ Therefore, programmers must make sure to either declare this class
+ as friend (preferred) or to always declare invariant functions and
+ base types @c typedef as public members.
+
+@see @RefSect{advanced.access_specifiers, Access Specifiers}
+*/
+class access { // Non-copyable (see below).
+/** @cond */
+private: // No public APIs (so users cannot use it directly by mistake).
+
+ access(); // Should never be constructed (not even internally).
+ ~access();
+
+ // No boost::noncopyable to avoid its overhead when contracts disabled.
+ access(access&);
+ access& operator=(access&);
+
+ #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(has_base_types,
+ BOOST_CONTRACT_BASES_TYPEDEF)
+
+ template<class C>
+ struct base_types_of {
+ typedef typename C::BOOST_CONTRACT_BASES_TYPEDEF type;
+ };
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_INVARIANTS
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION(
+ has_static_invariant_f, BOOST_CONTRACT_STATIC_INVARIANT_FUNC)
+
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(
+ has_static_invariant_s, BOOST_CONTRACT_STATIC_INVARIANT_FUNC)
+
+ template<class C>
+ struct has_static_invariant : has_static_invariant_s<C, void,
+ boost::mpl::vector<> > {};
+
+ template<class C>
+ static void static_invariant() {
+ C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC();
+ }
+
+ template<class C>
+ class static_invariant_addr { // Class so to pass it as tparam.
+ typedef void (*func_ptr)();
+ public:
+ static func_ptr apply() {
+ return &C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC;
+ }
+ };
+
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION(
+ has_invariant_f, BOOST_CONTRACT_INVARIANT_FUNC)
+
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(
+ has_invariant_s, BOOST_CONTRACT_INVARIANT_FUNC)
+
+ template<class C>
+ struct has_cv_invariant : has_invariant_f<C, void, boost::mpl::vector<>,
+ boost::function_types::cv_qualified> {};
+
+ template<class C>
+ struct has_const_invariant : has_invariant_f<C, void, boost::mpl::
+ vector<>, boost::function_types::const_qualified> {};
+
+ template<class C>
+ static void cv_invariant(C const volatile* obj) {
+ BOOST_CONTRACT_DETAIL_DEBUG(obj);
+ obj->BOOST_CONTRACT_INVARIANT_FUNC();
+ }
+
+ template<class C>
+ static void const_invariant(C const* obj) {
+ BOOST_CONTRACT_DETAIL_DEBUG(obj);
+ obj->BOOST_CONTRACT_INVARIANT_FUNC();
+ }
+ #endif
+
+ // Friends (used to limit library's public API).
+ // NOTE: Using friends here and in all other places in this library
+ // does not increase compilation times (I experimented replacing all
+ // friends with public and got the same compilation times).
+ #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
+ /* is_friend = */ 1, OO, RR, FF, CC, AArgs);
+
+ BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
+ OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs)
+ #endif
+ #ifndef BOOST_CONTRACT_NO_INVARIANTS
+ template<typename RR, class CC>
+ friend class boost::contract::detail::cond_inv;
+ #endif
+/** @endcond */
+};
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/core/check_macro.hpp b/boost/contract/core/check_macro.hpp
new file mode 100644
index 0000000000..3ecc93ea82
--- /dev/null
+++ b/boost/contract/core/check_macro.hpp
@@ -0,0 +1,133 @@
+
+#ifndef BOOST_CONTRACT_CHECK_MACRO_HPP_
+#define BOOST_CONTRACT_CHECK_MACRO_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
+
+/** @file
+Macros for implementation checks.
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/noop.hpp>
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Preferred way to assert implementation check conditions.
+
+ It is preferred to use this macro instead of programming implementation
+ checks in a nullary functor passed to @RefClass{boost::contract::check}
+ constructor because this macro will completely remove implementation checks
+ from the code when @RefMacro{BOOST_CONTRACT_NO_CHECKS} is defined:
+
+ @code
+ void f() {
+ ...
+ BOOST_CONTRACT_CHECK(...);
+ ...
+ }
+ @endcode
+
+ @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and
+ @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels
+ predefined by this library for implementation checks.
+
+ @see @RefSect{advanced.implementation_checks, Implementation Checks}
+
+ @param cond Boolean condition to check within implementation code (function
+ body, etc.).
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_CHECK((cond)) will always work.)
+ */
+ #define BOOST_CONTRACT_CHECK(cond)
+#elif !defined(BOOST_CONTRACT_NO_CHECKS)
+ #include <boost/contract/detail/check.hpp>
+ #include <boost/contract/detail/assert.hpp>
+
+ #define BOOST_CONTRACT_CHECK(cond) \
+ BOOST_CONTRACT_DETAIL_CHECK(BOOST_CONTRACT_DETAIL_ASSERT(cond))
+#else
+ #define BOOST_CONTRACT_CHECK(cond) /* nothing */
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Preferred way to assert implementation check conditions that are
+ computationally expensive, at least compared to the cost of executing the
+ function body.
+
+ The specified condition will always be compiled and validated
+ syntactically, but it will not be evaluated at run-time unless
+ @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default).
+ This macro is defined by code equivalent to:
+
+ @code
+ #ifdef BOOST_CONTRACT_AUDITS
+ #define BOOST_CONTRACT_CHECK_AUDIT(cond) \
+ BOOST_CONTRACT_CHECK(cond)
+ #else
+ #define BOOST_CONTRACT_CHECK_AUDIT(cond) \
+ BOOST_CONTRACT_CHECK(true || cond)
+ #endif
+ @endcode
+
+ @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and
+ @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels
+ predefined by this library for implementation checks.
+ If there is a need, programmers are free to implement their own assertion
+ levels defining macros similar to the one above.
+
+ @see @RefSect{extras.assertion_levels, Assertion Levels}
+
+ @param cond Boolean condition to check within implementation code (function
+ body, etc.).
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_CHECK_AUDIT((cond)) will always work.)
+ */
+ #define BOOST_CONTRACT_CHECK_AUDIT(cond)
+#elif defined(BOOST_CONTRACT_AUDITS)
+ #define BOOST_CONTRACT_CHECK_AUDIT(cond) \
+ BOOST_CONTRACT_CHECK(cond)
+#else
+ #define BOOST_CONTRACT_CHECK_AUDIT(cond) \
+ BOOST_CONTRACT_DETAIL_NOEVAL(cond)
+#endif
+
+/**
+Preferred way to assert implementation check conditions that are computationally
+prohibitive, at least compared to the cost of executing the function body.
+
+The specified condition will always be compiled and validated
+syntactically, but it will never be evaluated at run-time.
+This macro is defined by code equivalent to:
+
+@code
+#define BOOST_CONTRACT_CHECK_AXIOM(cond) \
+ BOOST_CONTRACT_CHECK(true || cond)
+@endcode
+
+@RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and
+@RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels predefined
+by this library for implementation checks.
+If there is a need, programmers are free to implement their own assertion levels
+defining macros similar to the one above.
+
+@see @RefSect{extras.assertion_levels, Assertion Levels}
+
+@param cond Boolean condition to check within implementation code (function
+ body, etc.).
+ (This is not a variadic macro parameter so any comma it might
+ contain must be protected by round parenthesis,
+ @c BOOST_CONTRACT_CHECK_AXIOM((cond)) will always work.)
+*/
+#define BOOST_CONTRACT_CHECK_AXIOM(cond) \
+ BOOST_CONTRACT_DETAIL_NOEVAL(cond)
+
+#endif // #include guard
+
diff --git a/boost/contract/core/config.hpp b/boost/contract/core/config.hpp
new file mode 100644
index 0000000000..e33c2bff81
--- /dev/null
+++ b/boost/contract/core/config.hpp
@@ -0,0 +1,797 @@
+
+#ifndef BOOST_CONTRACT_CONFIG_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Configure this library compile-time and run-time behaviours.
+*/
+
+// IMPORTANT: This header MUST NOT #include any other header of this lib.
+// That way users can #include this header and not #include any of this lib
+// headers after that depending on the contract 0/1 macros below ensuring no
+// compilation overhead.
+
+// Export symbols when compiling as shared lib (for internal use only). (Named
+// after similar macros in all Boost libs.)
+// BOOST_CONTRACT_SOURCE
+
+// Disable automatic library selection for linking. (Named after similar macros
+// in all Boost libs.)
+// BOOST_CONTRACT_NO_LIB
+// BOOST_ALL_NO_LIB
+
+#if (!defined(BOOST_CONTRACT_DYN_LINK) && defined(BOOST_ALL_DYN_LINK)) || \
+ defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
+ /**
+ Define this macro to compile this library as a shared library (recommended).
+
+ If this macro is defined, this library is compiled so it can be linked
+ as a shared library (a.k.a., Dynamically Linked Library or DLL) to user
+ code.
+ Also, this library will automatically define this macro when Boost libraries
+ are built as dynamic libraries (e.g., defining @c BOOST_ALL_DYN_LINK).
+
+ @warning In general this library will correctly check contracts at
+ run-time only when compiled as a shared library, unless user
+ code checks contracts in a single program unit (e.g., a single
+ program with only statically linked libraries that check
+ contracts).
+ Therefore, it is recommended to build and use this library as
+ a dynamic library by defining this macro (or equivalently by
+ building all Boost libraries as dynamic libraries and
+ @c BOOST_ALL_DYN_LINK is defined).
+
+ @see @RefSect{getting_started.compilers_and_platforms, Compilers and
+ Platforms}
+ */
+ #define BOOST_CONTRACT_DYN_LINK
+#elif defined(BOOST_CONTRACT_DYN_LINK) && defined(BOOST_CONTRACT_STATIC_LINK)
+ #error "DYN_LINK defined with STATIC_LINK"
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Define this macro to compile this library as a static library (not
+ recommended).
+
+ If this macro is defined, this library is compiled so it can be linked
+ statically to user code.
+ This library build scripts will automatically define this macro when Boost
+ libraries are being built as static libraries.
+
+ @warning This library is not guaranteed to always work correctly at
+ run-time when this macro is defined (define
+ @RefMacro{BOOST_CONTRACT_DYN_LINK} or @c BOOST_ALL_DYN_LINK
+ instead).
+ However, this macro can be defined and this library can be
+ safely used as a static library for user code that checks
+ contracts in a single program unit (e.g., a single program with
+ only statically linked libraries that check contracts).
+
+ @see @RefSect{getting_started.compilers_and_platforms, Compilers and
+ Platforms}
+ */
+ #define BOOST_CONTRACT_STATIC_LINK
+#elif defined(BOOST_CONTRACT_STATIC_LINK) && defined(BOOST_CONTRACT_DYN_LINK)
+ #error "STATIC_LINK defined with DYN_LINK"
+#endif
+
+#ifdef BOOST_CONTRACT_HEADER_ONLY
+ #error "leave DYN_LINK and STATIC_LINK undefined instead"
+#elif (!defined(BOOST_CONTRACT_DYN_LINK) && \
+ !defined(BOOST_CONTRACT_STATIC_LINK)) || \
+ defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
+ /**
+ Automatically defined by this library when it is being used as a header-only
+ library (not recommended).
+
+ This library will define this macro when users do not define
+ @RefMacro{BOOST_CONTRACT_DYN_LINK} (or @c BOOST_ALL_DYN_LINK) and
+ @RefMacro{BOOST_CONTRACT_STATIC_LINK} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ When used as a header-only library, this library code does not have to be
+ compiled separately from user code, this library headers are simply included
+ and compiled as part of the user program.
+
+ @warning This library is not guaranteed to always work correctly at
+ run-time when this macro is defined (define
+ @RefMacro{BOOST_CONTRACT_DYN_LINK} or @c BOOST_ALL_DYN_LINK
+ instead).
+ However, this macro can be defined and this library can be
+ safely used as a header-only library for user code that checks
+ contracts in a single program unit (e.g., a single program with
+ only statically linked libraries that check contracts).
+
+ @see @RefSect{getting_started.compilers_and_platforms, Compilers and
+ Platforms}
+ */
+ #define BOOST_CONTRACT_HEADER_ONLY
+#endif
+
+#if (!defined(BOOST_CONTRACT_DISABLE_THREADS) && \
+ defined(BOOST_DISABLE_THREADS)) || \
+ defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
+ /**
+ Define this macro to not lock internal library data for thread safety
+ (undefined by default).
+
+ Defining this macro will make the library implementation code not thread
+ safe so this macro should not be defined unless the library is being used by
+ single-threaded applications only.
+ This library will automatically define this macro when Boost libraries are
+ built without threads (e.g., defining @c BOOST_DISABLE_THREADS).
+
+ @note When this macro is left undefined this library needs to internally
+ use some sort of global lock (to ensure contract checking is
+ globally disabled when other contracts are being checked and also to
+ safely access failure handler functors).
+ That could introduce an undesired amount of synchronization in some
+ multi-threaded applications.
+
+ @see @RefSect{contract_programming_overview.assertions, Assertions}
+ */
+ #define BOOST_CONTRACT_DISABLE_THREADS
+#endif
+
+#ifndef BOOST_CONTRACT_MAX_ARGS
+ /**
+ Maximum number of arguments for public function overrides on compilers that
+ do not support variadic templates (default to @c 10).
+
+ On compilers that do not support variadic templates, this macro is defined
+ to the maximum number of arguments that public function overrides can have
+ and pass to @RefFunc{boost::contract::public_function} (users can redefine
+ this macro to a different value).
+ On compilers that support variadic templates, this macro has no effect.
+
+ @note Regardless of the value of this macro and of compiler support for
+ variadic templates, there is an intrinsic limit of about 18
+ arguments for public function overrides (because of similar limits
+ in Boost.MPL and Boost.FunctionTypes internally used by this
+ library).
+
+ @see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+ */
+ #define BOOST_CONTRACT_MAX_ARGS 10
+#endif
+
+#ifndef BOOST_CONTRACT_BASES_TYPEDEF
+ /**
+ Define the name of the base type @c typedef (@c base_types by default).
+
+ This macro expands to the name of the @c typedef that lists the base
+ classes for subcontracting via @RefMacro{BOOST_CONTRACT_BASE_TYPES}:
+
+ @code
+ class u :
+ #define BASES public b, private w
+ BASES
+ {
+ friend class boost::contract:access;
+
+ typedef BOOST_CONTRACT_BASES(BASES) BOOST_CONTRACT_TYPEDEF;
+ #undef BASES
+
+ ...
+ };
+ @endcode
+
+ Users can redefine this macro if the @c typedef must have a name different
+ from @c base_types (because of name clashes in user code, etc.).
+
+ @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes}
+ */
+ #define BOOST_CONTRACT_BASES_TYPEDEF base_types
+#endif
+
+#ifndef BOOST_CONTRACT_INVARIANT_FUNC
+ /**
+ Define the name of the class invariant member function (@c invariant by
+ default).
+
+ This macro expands to the name of the @c const and <c>const volatile</c>
+ member functions that check class invariants and volatile class invariants
+ respectively:
+
+ @code
+ class u {
+ friend class boost::contract::access;
+
+ void BOOST_CONTRACT_INVARIANT_FUNC() const {
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ void BOOST_CONTRACT_INVARIANT_FUNC() const volatile {
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ ...
+ };
+ @endcode
+
+ Users can redefine this macro if the invariant functions must have a name
+ different from @c invariant (because of name clashes in user code, etc.).
+
+ @note C++ does not allow to overload member functions based on the
+ @c static classifier, so this macro must always be defined to be
+ different than the function name defined for
+ @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT_FUNC}.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+ */
+ #define BOOST_CONTRACT_INVARIANT_FUNC invariant
+#endif
+
+#ifndef BOOST_CONTRACT_STATIC_INVARIANT_FUNC
+ /**
+ Define the name of the static invariant member function (@c static_invariant
+ by default).
+
+ This macro expands to the name of the @c static member function that checks
+ static class invariants:
+
+ @code
+ class u {
+ friend class boost::contract::access;
+
+ static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() {
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ ...
+ };
+ @endcode
+
+ Users can redefine this macro if the static invariant function must have a
+ name different from @c static_invariant (because of name clashes in user
+ code, etc.).
+
+ @note C++ does not allow to overload member functions based on the
+ @c static classifier, so this macro must always be defined to be
+ different than the function name defined for
+ @RefMacro{BOOST_CONTRACT_INVARIANT_FUNC}.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants}
+ */
+ #define BOOST_CONTRACT_STATIC_INVARIANT_FUNC static_invariant
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Disable some compile-time errors generated by this library (undefined by
+ default).
+
+ Defining this macro disables a number of static checks and related
+ compile-time errors generated by this library, for example:
+
+ @li The static invariant member @c BOOST_CONTRACT_STATIC_INVARIANT_FUNC
+ function must be declared @c static.
+ @li Non-static invariant member functions @c BOOST_CONTRACT_INVARIANT_FUNC
+ must be declared either @c const, <c>const volatile</c>, or
+ <c>volatile const</c>.
+ @li Derived classes that program contracts for one or more public function
+ overrides via @RefFunc{boost::contract::public_function} must also
+ define the @RefMacro{BOOST_CONTRACT_BASE_TYPES} @c typedef.
+
+ In general, it is not recommended to define this macro because these
+ compile-time checks can guard against misuses of this library.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{tutorial.base_classes__subcontracting_, Base Classes}
+ */
+ #define BOOST_CONTRACT_PERMISSIVE
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Code block to execute if contracts are not assigned to a
+ @RefClass{boost::contract::check} variable (undefined by default and
+ executes @c BOOST_ASSERT(false)).
+
+ In general, there is a logic error in the program when contracts are not
+ assigned to a local variable of type @RefClass{boost::contract::check}
+ (because that is a misuse of this library).
+ Therefore, by default (i.e., when this macro is not defined) this library
+ calls <c>BOOST_ASSERT(false)</c> in those cases.
+ If this macro is defined, this library will execute the code expanded by the
+ macro instead of calling @c BOOST_ASSERT(false) (if programmers prefer to
+ throw an exception, etc.).
+
+ This macro can be defined to be any block of code (use empty curly brackets
+ @c {} to generate no error), for example (on GCC):
+ @code
+ -DBOOST_CONTRACT_ON_MISSING_CHECK_DECL='{ throw std::logic_error("missing contract check declaration"); }'
+ @endcode
+
+ @see @RefSect{tutorial, Tutorial}
+ */
+ #define BOOST_CONTRACT_ON_MISSING_CHECK_DECL
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Define this macro to not disable other assertions while checking
+ preconditions (undefined by default).
+
+ Not disabling other assertions while checking preconditions can lead to
+ infinite recursion in user code so by default this macro is not defined.
+
+ However, the @RefSect{bibliography, [1962]} proposal does not disable
+ assertions while checking preconditions because arguments can reach the
+ function body unchecked if assertions are disabled while checking
+ preconditions (e.g., when these same functions bodies are called to check
+ the preconditions in question).
+ This macro can be defined to obtain the behaviour specified in
+ @RefSect{bibliography, [1962]} (at the risk of infinite recursion).
+
+ @see @RefSect{contract_programming_overview.feature_summary,
+ Feature Summary}
+ */
+ #define BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Define this macro to not disable any assertion while checking other
+ assertions (undefined by default).
+
+ Not disabling assertions while checking other assertions can lead to
+ infinite recursion in user code so by default this macro is not defined.
+ (Defining this macro automatically implies that other assertion checking is
+ disabled while checking preconditions as if
+ @RefMacro{BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION} was also
+ defined.)
+
+ @see @RefSect{contract_programming_overview.feature_summary,
+ Feature Summary}
+ */
+ #define BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Define this macro to evaluate and check audit assertions at run-time
+ (undefined by default).
+
+ Audit assertions and implementation checks programmed via
+ @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and
+ @RefMacro{BOOST_CONTRACT_CHECK_AUDIT} are always compiled and validated
+ syntactically.
+ However, they are not evaluated and checked at run-time unless
+ this macro is defined (because these conditions can be computationally
+ expensive, at least compared to the cost of executing the function body).
+
+ @see @RefSect{extras.assertion_levels, Assertion Levels}
+ */
+ #define BOOST_CONTRACT_AUDITS
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ If defined, this library does not perform implementation checks (undefined
+ by default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ implementation checks.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of implementation checks or use
+ @RefMacro{BOOST_CONTRACT_CHECK} (recommended).
+
+ @see @RefSect{advanced.implementation_checks,
+ Implementation Checks},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_CHECKS
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ If defined, this library does not check preconditions (undefined by
+ default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking preconditions.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of preconditions or use the macros
+ defined in @c boost/contract_macro.hpp (recommended only for applications
+ where it is truly necessary to completely remove contract code compilation
+ from production code).
+
+ @see @RefSect{tutorial.preconditions, Preconditions},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_PRECONDITIONS
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ If defined, this library does not check postconditions (undefined by
+ default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking postconditions.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of postconditions or use the macros
+ defined in @c boost/contract_macro.hpp (recommended only for applications
+ where it is truly necessary to completely remove contract code compilation
+ from production code).
+
+ It is necessary to disable both postconditions and exception guarantees
+ defining @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} in order to disable old value copies
+ (see @RefMacro{BOOST_CONTRACT_NO_OLDS}).
+
+ @see @RefSect{tutorial.postconditions, Postconditions},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_POSTCONDITIONS
+#endif
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ If defined, this library does not check exception guarantees (undefined by
+ default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking exception guarantees.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of exception guarantees or use the
+ macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ It is necessary to disable both postconditions and exception guarantees
+ defining @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} in order to disable old value copies
+ (see @RefMacro{BOOST_CONTRACT_NO_OLDS}).
+
+ @see @RefSect{tutorial.exception_guarantees, Exception Guarantees},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_EXCEPTS
+#endif
+
+#if defined(BOOST_CONTRACT_DETAIL_DOXYGEN) || \
+ ( \
+ !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_INVARIANTS) \
+ )
+ /**
+ If defined, this library does not check class invariants at entry (undefined
+ by default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking class invariants at entry.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of entry class invariants or use the
+ macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ This macro is automatically defined when
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+#endif
+
+#if defined(BOOST_CONTRACT_DETAIL_DOXYGEN) || \
+ ( \
+ !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_INVARIANTS) \
+ )
+ /**
+ If defined, this library does not check class invariants at exit (undefined
+ by default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking class invariants at exit.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of exit class invariants or use the
+ macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ This macro is automatically defined when
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_EXIT_INVARIANTS
+#endif
+
+#if !defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS)
+ /**
+ If defined, this library does not check class invariants (undefined by
+ default).
+
+ If this macro is defined, this library internal code is also optimized to
+ reduce compile-time (not just run-time) overhead associated with
+ checking class invariants.
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of class invariants or use the
+ macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ Defining this macro is equivalent to defining both
+ @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS} and
+ @RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}.
+
+ @see @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.disable_contract_checking,
+ Disable Contract Checking},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_INVARIANTS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_OLDS
+ #error "define NO_POSTCONDITIONS and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when old value copies are not to be
+ performed.
+
+ This library will define this macro when users define both
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of old value copies or use the
+ macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ @see @RefSect{tutorial.old_values, Old Values},
+ @RefSect{advanced.old_value_copies_at_body,
+ Old Value Copies at Body},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_OLDS
+#endif
+
+// Ctor pre checked separately and outside RAII so not part of this #define.
+#ifdef BOOST_CONTRACT_NO_CONSTRUCTORS
+ #error "define NO_INVARIANTS, NO_POSTCONDITIONS, and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when contracts are not checked for
+ constructors.
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of contracts for constructors or use
+ the macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ @note Constructor preconditions are checked separately by
+ @RefClass{boost::contract::constructor_precondition} so they are
+ disabled by @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} instead.
+
+ @see @RefSect{tutorial.constructors, Constructors},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_CONSTRUCTORS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_DESTRUCTORS
+ #error "define NO_INVARIANTS, NO_POSTCONDITIONS, and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when contracts are not checked for
+ destructors.
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of contracts for destructors or use
+ the macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ @see @RefSect{tutorial.destructors, Destructors},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_DESTRUCTORS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when contracts are not checked for
+ public functions.
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS},
+ @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of contracts for public functions or
+ use the macros defined in @c boost/contract_macro.hpp (recommended only for
+ applications where it is truly necessary to completely remove contract code
+ compilation from production code).
+
+ @see @RefSect{tutorial.public_functions, Public Functions},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_FUNCTIONS
+ #error "define NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when contracts are not checked for
+ non-member, private and protected functions.
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of contracts for non-member,
+ private and protected functions, or use the macros defined in
+ @c boost/contract_macro.hpp (recommended only for applications where it is
+ truly necessary to completely remove contract code compilation from
+ production code).
+
+ This macro is also used when contracts are not checked for private and
+ protected functions, lambda functions, code blocks, loops, etc.
+
+ @see @RefSect{tutorial.non_member_functions, Non-Member Functions},
+ @RefSect{advanced.private_and_protected_functions,
+ Private and Protected Functions},
+ @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__,
+ Lambdas\, Loops\, Code Blocks},
+ @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_FUNCTIONS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_CONDITIONS
+ #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, and NO_EXCEPTS instead"
+#elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS)
+ /**
+ Automatically defined by this library when contracts are not checked for
+ preconditions, postconditions, exceptions guarantees, and class invariants
+ (excluding implementation checks).
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}, and
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ Users can manually program @c \#ifndef statements in their code using this
+ macro to completely disable compilation of contracts within specifications
+ or use the macros defined in @c boost/contract_macro.hpp (recommended only
+ for applications where it is truly necessary to completely remove contract
+ code compilation from production code).
+
+ @see @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_CONDITIONS
+#endif
+
+#ifdef BOOST_CONTRACT_NO_ALL
+ #error "define NO_INVARIANTS, NO_PRECONDITIONS, NO_POSTCONDITIONS, NO_EXCEPTS, and NO_CHECKS instead"
+#elif defined(BOOST_CONTRACT_NO_INVARIANTS) && \
+ defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ defined(BOOST_CONTRACT_NO_EXCEPTS) && \
+ defined(BOOST_CONTRACT_NO_CHECKS)
+ /**
+ Automatically defined by this library when contracts are not checked at all.
+
+ This library will define this macro when users define all
+ @RefMacro{BOOST_CONTRACT_NO_INVARIANTS},
+ @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS},
+ @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}, and
+ @RefMacro{BOOST_CONTRACT_NO_CHECKS} (this macro is not a configuration
+ macro and this library will generate a compile-time error if users try to
+ define it directly).
+ For example, users can manually program @c \#ifndef statements in their code
+ using this macro to avoid including the @c boost/contract.hpp header all
+ together:
+
+ @code
+ #include <boost/contract/core/config.hpp>
+ #ifndef BOOST_CONTRACT_NO_ALL
+ #include <boost/contract.hpp>
+ #endif
+ @endcode
+
+ Or, use the @c boost/contract_macro.hpp header and related macros instead
+ (because the @c boost/contract_macro.hpp header is already optimized to not
+ include other headers from this library when contracts are not checked, but
+ recommended only for applications where it is truly necessary to completely
+ remove contract code compilation from production code).
+
+ @see @RefSect{extras.disable_contract_compilation__macro_interface_,
+ Disable Contract Compilation}
+ */
+ #define BOOST_CONTRACT_NO_ALL
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/core/constructor_precondition.hpp b/boost/contract/core/constructor_precondition.hpp
new file mode 100644
index 0000000000..7a7fa753aa
--- /dev/null
+++ b/boost/contract/core/constructor_precondition.hpp
@@ -0,0 +1,122 @@
+
+#ifndef BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_HPP_
+#define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_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
+
+/** @file
+Program preconditions for constructors.
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ #include <boost/contract/core/exception.hpp>
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ #include <boost/contract/detail/checking.hpp>
+ #endif
+#endif
+
+namespace boost { namespace contract {
+
+/**
+Program preconditions for constructors.
+
+This class must be the very first base of the class declaring the
+constructor for which preconditions are programmed (that way constructor
+arguments can be checked by preconditions even before they are used to
+initialize other base classes):
+
+@code
+ class u
+ #define BASES private boost::contract::constructor_precondition<u>, \
+ public b
+ : BASES
+ {
+ ...
+ #undef BASES
+
+ public:
+ explicit u(unsigned x) :
+ boost::contract::constructor_precondition<u>([&] {
+ BOOST_CONTRACT_ASSERT(x != 0);
+ ...
+ }),
+ b(1.0 / float(x))
+ {
+ ...
+ }
+
+ ...
+ };
+@endcode
+
+User-defined classes should inherit privately from this class (to not alter the
+public interface of user-defined classes).
+In addition, this class should never be declared as a virtual base (because
+virtual bases are initialized only once across the entire inheritance hierarchy
+preventing preconditions of other base classes from being checked).
+
+Unions cannot have base classes in C++ so this class can be used to declare a
+local object within the constructor definition just before
+@RefFunc{boost::contract::constructor} is used (see
+@RefSect{extras.unions, Unions}).
+
+@see @RefSect{tutorial.constructors, Constructors}
+
+@tparam Class The class type of the constructor for which preconditions are
+ being programmed.
+*/
+template<class Class>
+class constructor_precondition { // Copyable (has no data).
+public:
+ /**
+ Construct this object without specifying constructor preconditions.
+
+ This is implicitly called for those constructors of the contracted class
+ that do not specify preconditions.
+
+ @note Calling this default constructor should amount to negligible
+ compile-time and run-time overheads (likely to be optimized away
+ completely by most compilers).
+ */
+ constructor_precondition() {}
+
+ /**
+ Construct this object specifying constructor preconditions.
+
+ @param f Nullary functor called by this library to check constructor
+ preconditions @c f().
+ Assertions within this functor call are usually programmed
+ using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown
+ by a call to this functor indicates a contract failure (and will
+ result in this library calling
+ @RefFunc{boost::contract::precondition_failure}).
+ This functor should capture variables by (constant) value, or
+ better by (constant) reference to avoid extra copies.
+ */
+ template<typename F>
+ explicit constructor_precondition(F const& f) {
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ try {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ if(boost::contract::detail::checking::already()) return;
+ #ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
+ boost::contract::detail::checking k;
+ #endif
+ #endif
+ f();
+ } catch(...) { precondition_failure(from_constructor); }
+ #endif
+ }
+
+ // Default copy operations (so user's derived classes can be copied, etc.).
+};
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/core/exception.hpp b/boost/contract/core/exception.hpp
new file mode 100644
index 0000000000..2a1d144dd2
--- /dev/null
+++ b/boost/contract/core/exception.hpp
@@ -0,0 +1,953 @@
+
+#ifndef BOOST_CONTRACT_EXCEPTION_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Handle contract assertion failures.
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so trivial headers only.
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/declspec.hpp> // No compile-time overhead.
+#include <boost/function.hpp>
+#include <boost/config.hpp>
+#include <exception>
+#include <string>
+
+// NOTE: This code should not change (not even its impl) based on the
+// CONTRACT_NO_... macros. For example, preconditions_failure() should still
+// all the set precondition failure handler even when NO_PRECONDITIONS is
+// #defined, because user code might explicitly call precondition_failure()
+// (for whatever reason...). Otherwise, the public API of this lib will change.
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+// Needed for `std::` prefix to show (but removed via `EXCLUDE_SYMBOLS=std`).
+namespace std {
+ class exception {};
+ class bad_cast {};
+}
+#endif
+
+namespace boost { namespace contract {
+
+/**
+Public base class for all exceptions directly thrown by this library.
+
+This class does not inherit from @c std::exception because exceptions deriving
+from this class will do that (inheriting from @c std::exception,
+@c std::bad_cast, etc.).
+
+@see @RefClass{boost::contract::assertion_failure},
+ @RefClass{boost::contract::bad_virtual_result_cast},
+ etc.
+*/
+class BOOST_CONTRACT_DETAIL_DECLSPEC exception {
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This is declared @c noexcept (or @c throw() before C++11).
+ */
+ virtual ~exception() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+};
+
+#ifdef BOOST_MSVC
+ #pragma warning(push)
+ #pragma warning(disable: 4275) // Bases w/o DLL spec (bad_cast, etc).
+ #pragma warning(disable: 4251) // Members w/o DLL spec (string for what_).
+#endif
+
+/**
+Exception thrown when inconsistent return values are passed to overridden
+virtual public functions.
+
+This exception is internally thrown by this library when programmers specify
+return values for public function overrides in derived classes that are not
+consistent with the return types of the virtual public functions being
+overridden in the base classes.
+This allows this library to give more descriptive error messages in such cases.
+
+@see @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+*/
+class BOOST_CONTRACT_DETAIL_DECLSPEC bad_virtual_result_cast : // Copy (as str).
+ public std::bad_cast, public boost::contract::exception {
+public:
+ /**
+ Construct this object with the name of the from- and to- result types.
+
+ @param from_type_name Name of the from-type (source of the cast).
+ @param to_type_name Name of the to-type (destination of the cast).
+ */
+ explicit bad_virtual_result_cast(char const* from_type_name,
+ char const* to_type_name);
+
+ /**
+ Destruct this object.
+
+ @b Throws: This is declared @c noexcept (or @c throw() before C++11).
+ */
+ virtual ~bad_virtual_result_cast()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+
+ /**
+ Description for this error (containing both from- and to- type names).
+
+ @b Throws: This is declared @c noexcept (or @c throw() before C++11).
+ */
+ virtual char const* what() const
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+
+/** @cond */
+private:
+ std::string what_;
+/** @endcond */
+};
+
+/**
+Exception typically used to report a contract assertion failure.
+
+This exception is thrown by code expanded by @RefMacro{BOOST_CONTRACT_ASSERT}
+(but it can also be thrown by user code programmed manually without that macro).
+This exception is typically used to report contract assertion failures because
+it contains detailed information about the file name, line number, and source
+code of the asserted condition (so it can be used by this library to provide
+detailed error messages).
+However, any other exception can be used to report a contract assertion failure
+(including user-defined exceptions).
+
+This library will call the appropriate contract failure handler function
+(@RefFunc{boost::contract::precondition_failure}, etc.) when this or any other
+exception is thrown while checking contracts (by default, these failure handler
+functions print an error message to @c std::cerr and terminate the program, but
+they can be customized to take any other action).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+*/
+class BOOST_CONTRACT_DETAIL_DECLSPEC assertion_failure : // Copy (as str, etc.).
+ public std::exception, public boost::contract::exception {
+public:
+ /**
+ Construct this object with file name, line number, and source code text of
+ an assertion condition (all optional).
+
+ This constructor can also be used to specify no information (default
+ constructor), or to specify only file name and line number but not source
+ code text (because of the parameter default values).
+
+ @param file Name of the file containing the assertion (usually set using
+ <c>__FILE__</c>).
+ @param line Number of the line containing the assertion (usually set using
+ <c>__LINE__</c>).
+ @param code Text listing the source code of the assertion condition.
+ */
+ explicit assertion_failure(char const* file = "", unsigned long line = 0,
+ char const* code = "");
+
+ /**
+ Construct this object only with the source code text of the assertion
+ condition.
+ @param code Text listing the source code of the assertion condition.
+ */
+ explicit assertion_failure(char const* code);
+
+ /**
+ Destruct this object.
+
+ @b Throws: This is declared @c noexcept (or @c throw() before C++11).
+ */
+ virtual ~assertion_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+
+ /**
+ String describing the failed assertion.
+
+ @b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+ @return A string formatted similarly to the following:
+ <c>assertion "`code()`" failed: file "`file()`", line \`line()\`</c>.
+ File, line, and code will be omitted from this string if they were
+ not specified when constructing this object.
+ */
+ virtual char const* what() const
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+
+ /**
+ Name of the file containing the assertion.
+
+ @return File name as specified at construction (or @c "" if no file was
+ specified).
+ */
+ char const* file() const;
+
+ /**
+ Number of the line containing the assertion.
+
+ @return Line number as specified at construction (or @c 0 if no line number
+ was specified).
+ */
+ unsigned long line() const;
+
+ /**
+ Text listing the source code of the assertion condition.
+
+ @return Assertion condition source code as specified at construction (or
+ @c "" if no source code text was specified).
+ */
+ char const* code() const;
+
+/** @cond */
+private:
+ void init();
+
+ char const* file_;
+ unsigned long line_;
+ char const* code_;
+ std::string what_;
+/** @endcond */
+};
+
+#ifdef BOOST_MSVC
+ #pragma warning(pop)
+#endif
+
+/**
+Indicate the kind of operation where the contract assertion failed.
+
+This is passed as a parameter to the assertion failure handler functions.
+For example, it might be necessary to know in which operation an assertion
+failed to make sure exceptions are never thrown from destructors, not even
+when contract failure handlers are programmed by users to throw exceptions
+instead of terminating the program.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}
+*/
+enum from {
+ /** Assertion failed when checking contracts for constructors. */
+ from_constructor,
+
+ /** Assertion failed when checking contracts for destructors . */
+ from_destructor,
+
+ /**
+ Assertion failed when checking contracts for functions (members or not).
+ */
+ from_function
+};
+
+/**
+Type of assertion failure handler functions (with @c from parameter).
+
+Assertion failure handler functions specified by this type must be functors
+returning @c void and taking a single parameter of type
+@RefEnum{boost::contract::from}.
+For example, this is used to specify contract failure handlers for class
+invariants, preconditions, postconditions, and exception guarantees.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}
+*/
+typedef boost::function<void (from)> from_failure_handler;
+
+/**
+Type of assertion failure handler functions (without @c from parameter).
+
+Assertion failure handler functions specified by this type must be nullary
+functors returning @c void.
+For example, this is used to specify contract failure handlers for
+implementation checks.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure}
+*/
+typedef boost::function<void ()> failure_handler;
+
+/** @cond */
+namespace exception_ {
+ // Check failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ failure_handler const& set_check_failure_unlocked(failure_handler const& f)
+ BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ failure_handler const& set_check_failure_locked(failure_handler const& f)
+ BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ failure_handler get_check_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ failure_handler get_check_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void check_failure_unlocked() /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void check_failure_locked() /* can throw */;
+
+ // Precondition failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_pre_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_pre_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_pre_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_pre_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void pre_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void pre_failure_locked(from where) /* can throw */;
+
+ // Postcondition failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_post_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_post_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_post_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_post_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void post_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void post_failure_locked(from where) /* can throw */;
+
+ // Except failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_except_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_except_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_except_failure_unlocked()
+ BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_except_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void except_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void except_failure_locked(from where) /* can throw */;
+
+ // Old-copy failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_old_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_old_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_old_failure_unlocked() BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_old_failure_locked() BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void old_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void old_failure_locked(from where) /* can throw */;
+
+ // Entry invariant failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_entry_inv_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_entry_inv_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_entry_inv_failure_unlocked()
+ BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_entry_inv_failure_locked()
+ BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void entry_inv_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void entry_inv_failure_locked(from where) /* can throw */;
+
+ // Exit invariant failure.
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const& set_exit_inv_failure_unlocked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler const&set_exit_inv_failure_locked(
+ from_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_exit_inv_failure_unlocked()
+ BOOST_NOEXCEPT_OR_NOTHROW;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ from_failure_handler get_exit_inv_failure_locked()
+ BOOST_NOEXCEPT_OR_NOTHROW;
+
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void exit_inv_failure_unlocked(from where) /* can throw */;
+ BOOST_CONTRACT_DETAIL_DECLSPEC
+ void exit_inv_failure_locked(from where) /* can throw */;
+}
+/** @endcond */
+
+} } // namespace
+
+/** @cond */
+#ifdef BOOST_CONTRACT_HEADER_ONLY
+ // NOTE: This header must be included in the middle of this file (because
+ // its impl depends on both from and assert_failure types). This is not
+ // ideal, but it is better than splitting this file into multiple
+ // independent ones because all content in this file is logically related
+ // from the user prospective.
+ #include <boost/contract/detail/inlined/core/exception.hpp>
+#endif
+/** @endcond */
+
+namespace boost { namespace contract {
+
+// Following must be inline for static linkage (no DYN_LINK and no HEADER_ONLY).
+
+/**
+Set failure handler for implementation checks.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.implementation_checks, Implementation Checks}
+*/
+inline failure_handler const& set_check_failure(failure_handler const& f)
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_check_failure_locked(f);
+ #else
+ return exception_::set_check_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for implementation checks.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.implementation_checks, Implementation Checks}
+*/
+inline failure_handler get_check_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_check_failure_locked();
+ #else
+ return exception_::get_check_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for implementation checks.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on implementation check failures (not the
+ default).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.implementation_checks, Implementation Checks}
+*/
+inline void check_failure() /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::check_failure_locked();
+ #else
+ exception_::check_failure_unlocked();
+ #endif
+}
+
+/**
+Set failure handler for preconditions.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.preconditions, Preconditions}
+*/
+inline from_failure_handler const& set_precondition_failure(from_failure_handler
+ const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_pre_failure_locked(f);
+ #else
+ return exception_::set_pre_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for preconditions.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.preconditions, Preconditions}
+*/
+inline from_failure_handler get_precondition_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_pre_failure_locked();
+ #else
+ return exception_::get_pre_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for preconditions.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default).
+
+@param where Operation that failed the contract assertion (when this function
+ is called by this library, this parameter will never be
+ @c from_destructor because destructors do not have
+ preconditions).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.preconditions, Preconditions}
+*/
+inline void precondition_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::pre_failure_locked(where);
+ #else
+ exception_::pre_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for postconditions.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., fr
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.postconditions, Postconditions}
+*/
+inline from_failure_handler const& set_postcondition_failure(
+ from_failure_handler const& f
+) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_post_failure_locked(f);
+ #else
+ return exception_::set_post_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for postconditions.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.postconditions, Postconditions}
+*/
+inline from_failure_handler get_postcondition_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_post_failure_locked();
+ #else
+ return exception_::get_post_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for postconditions.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default).
+
+@param where Operation that failed the contract assertion (e.g., this might
+ be useful to program failure handler functors that never throw
+ from destructors, not even when they are programmed by users to
+ throw exceptions instead of terminating the program).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.postconditions, Postconditions}
+*/
+inline void postcondition_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::post_failure_locked(where);
+ #else
+ exception_::post_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for exception guarantees.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+*/
+inline from_failure_handler const& set_except_failure(from_failure_handler
+ const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_except_failure_locked(f);
+ #else
+ return exception_::set_except_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for exception guarantees.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+*/
+inline from_failure_handler get_except_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_except_failure_locked();
+ #else
+ return exception_::get_except_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for exception guarantees.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default),
+ however:
+
+@warning When this failure handler is called there is already an active
+ exception (the one that caused the exception guarantees to be
+ checked in the first place).
+ Therefore, programming this failure handler to throw yet another
+ exception will force C++ to automatically terminate the program.
+
+@param where Operation that failed the contract assertion.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+*/
+inline void except_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::except_failure_locked(where);
+ #else
+ exception_::except_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for old value copies at body.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body}
+*/
+inline from_failure_handler const& set_old_failure(from_failure_handler const&
+ f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_old_failure_locked(f);
+ #else
+ return exception_::set_old_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for old value copies at body.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body}
+*/
+inline from_failure_handler get_old_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_old_failure_locked();
+ #else
+ return exception_::get_old_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for old value copies at body.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default).
+
+@param where Operation that failed the old value copy (e.g., this might
+ be useful to program failure handler functors that never throw
+ from destructors, not even when they are programmed by users to
+ throw exceptions instead of terminating the program).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body}
+*/
+inline void old_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::old_failure_locked(where);
+ #else
+ exception_::old_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for class invariants at entry.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline from_failure_handler const& set_entry_invariant_failure(
+ from_failure_handler const& f
+)/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_entry_inv_failure_locked(f);
+ #else
+ return exception_::set_entry_inv_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for class invariants at entry.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline from_failure_handler get_entry_invariant_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_entry_inv_failure_locked();
+ #else
+ return exception_::get_entry_inv_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for class invariants at entry.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default).
+
+@param where Operation that failed the contract assertion (e.g., this might
+ be useful to program failure handler functors that never throw
+ from destructors, not even when they are programmed by users to
+ throw exceptions instead of terminating the program).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline void entry_invariant_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::entry_inv_failure_locked(where);
+ #else
+ return exception_::entry_inv_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for class invariants at exit.
+
+Set a new failure handler and returns it.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline from_failure_handler const& set_exit_invariant_failure(
+ from_failure_handler const& f
+) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::set_exit_inv_failure_locked(f);
+ #else
+ return exception_::set_exit_inv_failure_unlocked(f);
+ #endif
+}
+
+/**
+Return failure handler currently set for class invariants at exit.
+
+This is often called only internally by this library.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@return A copy of the failure handler currently set.
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline from_failure_handler get_exit_invariant_failure()
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ return exception_::get_exit_inv_failure_locked();
+ #else
+ return exception_::get_exit_inv_failure_unlocked();
+ #endif
+}
+
+/**
+Call failure handler for class invariants at exit.
+
+This is often called only internally by this library.
+
+@b Throws: This can throw in case programmers specify a failure handler that
+ throws exceptions on contract assertion failures (not the default).
+
+@param where Operation that failed the contract assertion (e.g., this might
+ be useful to program failure handler functors that never throw
+ from destructors, not even when they are programmed by users to
+ throw exceptions instead of terminating the program).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+inline void exit_invariant_failure(from where) /* can throw */ {
+ #ifndef BOOST_CONTRACT_DISABLE_THREADS
+ exception_::exit_inv_failure_locked(where);
+ #else
+ exception_::exit_inv_failure_unlocked(where);
+ #endif
+}
+
+/**
+Set failure handler for class invariants (at both entry and exit).
+
+This is provided for convenience and it is equivalent to call both
+@RefFunc{boost::contract::set_entry_invariant_failure} and
+@RefFunc{boost::contract::set_exit_invariant_failure} with the same functor
+parameter @p f.
+
+@b Throws: This is declared @c noexcept (or @c throw() before C++11).
+
+@param f New failure handler functor to set for both entry and exit invariants.
+
+@return Same failure handler functor @p f passed as parameter (e.g., for
+ concatenating function calls).
+
+@see @RefSect{advanced.throw_on_failures__and__noexcept__, Throw on Failure},
+ @RefSect{tutorial.class_invariants, Class Invariants},
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}
+*/
+/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
+from_failure_handler const& set_invariant_failure(from_failure_handler const& f)
+ /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/core/specify.hpp b/boost/contract/core/specify.hpp
new file mode 100644
index 0000000000..ef0bea9b09
--- /dev/null
+++ b/boost/contract/core/specify.hpp
@@ -0,0 +1,650 @@
+
+#ifndef BOOST_CONTRACT_SPECIFY_HPP_
+#define BOOST_CONTRACT_SPECIFY_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
+
+/** @file
+Specify preconditions, old value copies at body, postconditions, and exception
+guarantees
+
+Preconditions, old value copies at body, postconditions, and exception
+guarantees are all optionals but, when they are specified, they need to be
+specified in that order.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/detail/decl.hpp>
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/condition/cond_base.hpp>
+ #include <boost/contract/detail/condition/cond_post.hpp>
+ #include <boost/contract/detail/auto_ptr.hpp>
+ #include <boost/contract/detail/none.hpp>
+#endif
+#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ #include <boost/contract/detail/debug.hpp>
+#endif
+#include <boost/config.hpp>
+
+// NOTE: No inheritance for faster run-times (macros to avoid duplicated code).
+
+/* PRIVATE */
+
+/* @cond */
+
+// NOTE: Private copy ops below will force compile-time error is `auto c = ...`
+// is used instead of `check c = ...` but only up to C++17. C++17 strong copy
+// elision on function return values prevents this lib from generating a
+// compile-time error in those cases, but the lib will still generate a run-time
+// error according with ON_MISSING_CHECK_DECL.
+#if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \
+ private: \
+ boost::contract::detail::auto_ptr<cond_type > cond_; \
+ explicit class_type(cond_type* cond) : cond_(cond) {} \
+ class_type(class_type const& other) : cond_(other.cond_) {} \
+ class_type& operator=(class_type const& other) { \
+ cond_ = other.cond_; \
+ return *this; \
+ }
+
+ #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ cond_.release()
+#else
+ #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \
+ private: \
+ class_type() {} \
+ class_type(class_type const&) {} \
+ class_type& operator=(class_type const&) { return *this; }
+
+ #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ /* nothing */
+#endif
+
+#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \
+ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
+ cond_->set_pre(f); \
+ return specify_old_postcondition_except<VirtualResult>( \
+ BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#else
+ #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \
+ return specify_old_postcondition_except<VirtualResult>( \
+ BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#endif
+
+#ifndef BOOST_CONTRACT_NO_OLDS
+ #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \
+ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
+ cond_->set_old(f); \
+ return specify_postcondition_except<VirtualResult>( \
+ BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#else
+ #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \
+ return specify_postcondition_except<VirtualResult>( \
+ BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#endif
+
+#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \
+ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
+ cond_->set_post(f); \
+ return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#else
+ #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \
+ return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#endif
+
+#ifndef BOOST_CONTRACT_NO_EXCEPTS
+ #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \
+ BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
+ cond_->set_except(f); \
+ return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#else
+ #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \
+ return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
+#endif
+
+/* @endcond */
+
+/* CODE */
+
+namespace boost {
+ namespace contract {
+ class virtual_;
+
+ template<typename VR>
+ class specify_precondition_old_postcondition_except;
+
+ template<typename VR>
+ class specify_old_postcondition_except;
+
+ template<typename VR>
+ class specify_postcondition_except;
+
+ class specify_except;
+ }
+}
+
+namespace boost { namespace contract {
+
+/**
+Used to prevent setting other contract conditions after exception guarantees.
+
+This class has no member function so it is used to prevent specifying additional
+functors to check any other contract.
+This object is internally constructed by this library when users specify
+contracts calling @RefFunc{boost::contract::function} and similar functions
+(that is why this class does not have a public constructor).
+
+@see @RefSect{tutorial, Tutorial}
+*/
+class specify_nothing { // Privately copyable (as *).
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This can throw in case programmers specify failure handlers that
+ throw exceptions instead of terminating the program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~specify_nothing() BOOST_NOEXCEPT_IF(false) {}
+
+ // No set member function here.
+
+/** @cond */
+private:
+ BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_nothing,
+ boost::contract::detail::cond_base)
+
+ // Friends (used to limit library's public API).
+
+ friend class check;
+
+ template<typename VR>
+ friend class specify_precondition_old_postcondition_except;
+
+ template<typename VR>
+ friend class specify_old_postcondition_except;
+
+ template<typename VR>
+ friend class specify_postcondition_except;
+
+ friend class specify_except;
+/** @endcond */
+};
+
+/**
+Allow to specify exception guarantees.
+
+Allow to specify the functor this library will call to check exception
+guarantees.
+This object is internally constructed by this library when users specify
+contracts calling @RefFunc{boost::contract::function} and similar functions
+(that is why this class does not have a public constructor).
+
+@see @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+*/
+class specify_except { // Privately copyable (as *).
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This can throw in case programmers specify failure handlers that
+ throw exceptions instead of terminating the program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~specify_except() BOOST_NOEXCEPT_IF(false) {}
+
+ /**
+ Allow to specify exception guarantees.
+
+ @param f Nullary functor called by this library to check exception
+ guarantees @c f().
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::except_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+
+ @return After exception guarantees have been specified, the object returned
+ by this function does not allow to specify any additional contract.
+ */
+ template<typename F>
+ specify_nothing except(F const& f) {
+ BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_
+ }
+
+/** @cond */
+private:
+ BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_except,
+ boost::contract::detail::cond_base)
+
+ // Friends (used to limit library's public API).
+
+ friend class check;
+
+ template<typename VR>
+ friend class specify_precondition_old_postcondition_except;
+
+ template<typename VR>
+ friend class specify_old_postcondition_except;
+
+ template<typename VR>
+ friend class specify_postcondition_except;
+/** @endcond */
+};
+
+/**
+Allow to specify postconditions or exception guarantees.
+
+Allow to specify functors this library will call to check postconditions or
+exception guarantees.
+This object is internally constructed by this library when users specify
+contracts calling @RefFunc{boost::contract::function} and similar functions
+(that is why this class does not have a public constructor).
+
+@see @RefSect{tutorial.postconditions, Postconditions},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+
+@tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that function is either a virtual public
+ function or a public function override.
+ Otherwise, this type is always @c void.
+*/
+template<typename VirtualResult = void>
+class specify_postcondition_except { // Privately copyable (as *).
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This can throw in case programmers specify failure handlers that
+ throw exceptions instead of terminating the program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~specify_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
+
+ /**
+ Allow to specify postconditions.
+
+ @param f Functor called by this library to check postconditions
+ @c f(...).
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::postcondition_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+ This functor must be a nullary functor if @c VirtualResult is
+ @c void, otherwise it must be a unary functor accepting the
+ return value as a parameter of type <c>VirtualResult const&</c>
+ (to avoid extra copies of the return value, or of type
+ @c VirtualResult or <c>VirtualResult const</c> if extra copies
+ of the return value are irrelevant).
+
+ @return After postconditions have been specified, the object returned by
+ this function allows to optionally specify exception guarantees.
+ */
+ template<typename F>
+ specify_except postcondition(F const& f) {
+ BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
+ }
+
+ /**
+ Allow to specify exception guarantees.
+
+ @param f Nullary functor called by this library to check exception
+ guarantees @c f().
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::except_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+
+ @return After exception guarantees have been specified, the object returned
+ by this function does not allow to specify any additional contract.
+ */
+ template<typename F>
+ specify_nothing except(F const& f) {
+ BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_
+ }
+
+/** @cond */
+private:
+ BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
+ specify_postcondition_except,
+ boost::contract::detail::cond_post<typename
+ boost::contract::detail::none_if_void<VirtualResult>::type>
+ )
+
+ // Friends (used to limit library's public API).
+
+ friend class check;
+ friend class specify_precondition_old_postcondition_except<VirtualResult>;
+ friend class specify_old_postcondition_except<VirtualResult>;
+/** @endcond */
+};
+
+/**
+Allow to specify old value copies at body, postconditions, and exception
+guarantees.
+
+Allow to specify functors this library will call to copy old value at body,
+check postconditions, and check exception guarantees.
+This object is internally constructed by this library when users specify
+contracts calling @RefFunc{boost::contract::function} and similar functions
+(that is why this class does not have a public constructor).
+
+@see @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body},
+ @RefSect{tutorial.postconditions, Postconditions},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+
+@tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that function is either a virtual public
+ function or a public function override.
+ Otherwise, this type is always @c void.
+*/
+template<typename VirtualResult = void>
+class specify_old_postcondition_except { // Privately copyable (as *).
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This can throw in case programmers specify failure handlers that
+ throw exceptions instead of terminating the program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
+
+ /**
+ Allow to specify old value copies at body.
+
+ It should often be sufficient to initialize old value pointers as soon as
+ they are declared, without using this function (see
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body}).
+
+ @param f Nullary functor called by this library @c f() to assign old
+ value copies just before the body is executed but after entry
+ invariants (when they apply) and preconditions are checked.
+ Old value pointers within this functor call are usually assigned
+ using @RefMacro{BOOST_CONTRACT_OLDOF}.
+ Any exception thrown by a call to this functor will result in
+ this library calling @RefFunc{boost::contract::old_failure}
+ (because old values could not be copied to check postconditions
+ and exception guarantees).
+ This functor should capture old value pointers by references so
+ they can be assigned (all other variables needed to evaluate old
+ value expressions can be captured by (constant) value, or better
+ by (constant) reference to avoid extra copies).
+
+ @return After old value copies at body have been specified, the object
+ returned by this function allows to optionally specify
+ postconditions and exception guarantees.
+ */
+ template<typename F>
+ specify_postcondition_except<VirtualResult> old(F const& f) {
+ BOOST_CONTRACT_SPECIFY_OLD_IMPL_
+ }
+
+ /**
+ Allow to specify postconditions.
+
+ @param f Functor called by this library to check postconditions
+ @c f(...).
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::postcondition_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+ This functor must be a nullary functor if @c VirtualResult is
+ @c void, otherwise it must be a unary functor accepting the
+ return value as a parameter of type <c>VirtualResult const&</c>
+ (to avoid extra copies of the return value, or of type
+ @c VirtualResult or <c>VirtualResult const</c> if extra copies
+ of the return value are irrelevant).
+
+ @return After postconditions have been specified, the object returned by
+ this function allows to optionally specify exception guarantees.
+ */
+ template<typename F>
+ specify_except postcondition(F const& f) {
+ BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
+ }
+
+ /**
+ Allow to specify exception guarantees.
+
+ @param f Nullary functor called by this library to check exception
+ guarantees @c f().
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::except_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+
+ @return After exception guarantees have been specified, the object returned
+ by this function does not allow to specify any additional contract.
+ */
+ template<typename F>
+ specify_nothing except(F const& f) {
+ BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_
+ }
+
+/** @cond */
+private:
+ BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
+ specify_old_postcondition_except,
+ boost::contract::detail::cond_post<typename
+ boost::contract::detail::none_if_void<VirtualResult>::type>
+ )
+
+ // Friends (used to limit library's public API).
+
+ friend class check;
+ friend class specify_precondition_old_postcondition_except<VirtualResult>;
+
+ template<class C>
+ friend specify_old_postcondition_except<> constructor(C*);
+
+ template<class C>
+ friend specify_old_postcondition_except<> destructor(C*);
+/** @endcond */
+};
+
+/**
+Allow to specify preconditions, old value copies at body, postconditions, and
+exception guarantees.
+
+Allow to specify functors this library will call to check preconditions, copy
+old values at body, check postconditions, and check exception guarantees.
+This object is internally constructed by this library when users specify
+contracts calling @RefFunc{boost::contract::function} and similar functions
+(that is why this class does not have a public constructor).
+
+@see @RefSect{tutorial.preconditions, Preconditions},
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body},
+ @RefSect{tutorial.postconditions, Postconditions},
+ @RefSect{tutorial.exception_guarantees, Exception Guarantees}
+
+@tparam VirtualResult Return type of the enclosing function declaring the
+ contract if that function is either a virtual public
+ function or a public function override.
+ Otherwise, this type is always @c void.
+*/
+template<
+ typename VirtualResult /* = void (already in fwd decl from decl.hpp) */
+ #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ = void
+ #endif
+>
+class specify_precondition_old_postcondition_except { // Priv. copyable (as *).
+public:
+ /**
+ Destruct this object.
+
+ @b Throws: This can throw in case programmers specify failure handlers that
+ throw exceptions instead of terminating the program (see
+ @RefSect{advanced.throw_on_failures__and__noexcept__,
+ Throw on Failure}).
+ (This is declared @c noexcept(false) since C++11.)
+ */
+ ~specify_precondition_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
+
+ /**
+ Allow to specify preconditions.
+
+ @param f Nullary functor called by this library to check preconditions
+ @c f().
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::precondition_failure}).
+ This functor should capture variables by (constant) value, or
+ better by (constant) reference (to avoid extra copies).
+
+ @return After preconditions have been specified, the object returned by this
+ function allows to optionally specify old value copies at body,
+ postconditions, and exception guarantees.
+ */
+ template<typename F>
+ specify_old_postcondition_except<VirtualResult> precondition(F const& f) {
+ BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_
+ }
+
+ /**
+ Allow to specify old value copies at body.
+
+ It should often be sufficient to initialize old value pointers as soon as
+ they are declared, without using this function (see
+ @RefSect{advanced.old_value_copies_at_body, Old Value Copies at Body}).
+
+ @param f Nullary functor called by this library @c f() to assign old
+ value copies just before the body is executed but after entry
+ invariants (when they apply) and preconditions are checked.
+ Old value pointers within this functor call are usually assigned
+ using @RefMacro{BOOST_CONTRACT_OLDOF}.
+ Any exception thrown by a call to this functor will result in
+ this library calling @RefFunc{boost::contract::old_failure}
+ (because old values could not be copied to check postconditions
+ and exception guarantees).
+ This functor should capture old value pointers by references so
+ they can be assigned (all other variables needed to evaluate old
+ value expressions can be captured by (constant) value, or better
+ by (constant) reference to avoid extra copies).
+
+ @return After old value copies at body have been specified, the object
+ returned by this functions allows to optionally specify
+ postconditions and exception guarantees.
+ */
+ template<typename F>
+ specify_postcondition_except<VirtualResult> old(F const& f) {
+ BOOST_CONTRACT_SPECIFY_OLD_IMPL_
+ }
+
+ /**
+ Allow to specify postconditions.
+
+ @param f Functor called by this library to check postconditions
+ @c f(...).
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::postcondition_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+ This functor must be a nullary functor if @c VirtualResult is
+ @c void, otherwise it must be a unary functor accepting the
+ return value as a parameter of type <c>VirtualResult const&</c>
+ (to avoid extra copies of the return value, or of type
+ @c VirtualResult or <c>VirtualResult const</c> if extra copies
+ of the return value are irrelevant).
+
+ @return After postconditions have been specified, the object returned by
+ this function allows to optionally specify exception guarantees.
+ */
+ template<typename F>
+ specify_except postcondition(F const& f) {
+ BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
+ }
+
+ /**
+ Allow to specify exception guarantees.
+
+ @param f Nullary functor called by this library to check exception
+ guarantees @c f().
+ Assertions within this functor are usually programmed using
+ @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
+ call to this functor indicates a contract assertion failure (and
+ will result in this library calling
+ @RefFunc{boost::contract::except_failure}).
+ This functor should capture variables by (constant) references
+ (to access the values they will have at function exit).
+
+ @return After exception guarantees have been specified, the object returned
+ by this function does not allow to specify any additional contract.
+ */
+ template<typename F>
+ specify_nothing except(F const& f) {
+ BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_
+ }
+
+/** @cond */
+private:
+ BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
+ specify_precondition_old_postcondition_except,
+ boost::contract::detail::cond_post<typename
+ boost::contract::detail::none_if_void<VirtualResult>::type>
+ )
+
+ // Friends (used to limit library's public API).
+
+ friend class check;
+ friend specify_precondition_old_postcondition_except<> function();
+
+ template<class C>
+ friend specify_precondition_old_postcondition_except<> public_function();
+
+ template<class C>
+ friend specify_precondition_old_postcondition_except<> public_function(C*);
+
+ template<class C>
+ friend specify_precondition_old_postcondition_except<> public_function(
+ virtual_*, C*);
+
+ template<typename VR, class C>
+ friend specify_precondition_old_postcondition_except<VR> public_function(
+ virtual_*, VR&, C*);
+
+ BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
+ O, VR, F, C, Args, v, r, f, obj, args)
+/** @endcond */
+};
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/core/virtual.hpp b/boost/contract/core/virtual.hpp
new file mode 100644
index 0000000000..fcdd60555d
--- /dev/null
+++ b/boost/contract/core/virtual.hpp
@@ -0,0 +1,161 @@
+
+#ifndef BOOST_CONTRACT_VIRTUAL_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Handle virtual public functions with contracts (for subcontracting).
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#ifndef BOOST_CONTRACT_NO_CONDITIONS
+ #include <boost/contract/detail/decl.hpp>
+#endif
+#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ #include <boost/any.hpp>
+#endif
+#ifndef BOOST_CONTRACT_NO_OLDS
+ #include <boost/shared_ptr.hpp>
+ #include <queue>
+#endif
+
+namespace boost { namespace contract {
+
+#ifndef BOOST_CONTRACT_NO_CONDITIONS
+ namespace detail {
+ BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
+ /* is_friend = */ 0, OO, RR, FF, CC, AArgs);
+ }
+#endif
+
+/**
+Type of extra function parameter to handle contracts for virtual public
+functions (for subcontracting).
+
+Virtual public functions (and therefore also public function overrides)
+declaring contracts using this library must specify an extra function parameter
+at the very end of the parameter list.
+This parameter must be a pointer to this class and it must have default value
+@c 0 (i.e., @c nullptr).
+(This extra parameter is often named @c v in this documentation, but any name
+can be used.)
+
+In practice this extra parameter does not alter the calling interface of the
+enclosing function declaring the contract because it is always the very last
+parameter and it has a default value (so it can always be omitted when users
+call the function).
+This extra parameter must be passed to
+@RefFunc{boost::contract::public_function}, @RefMacro{BOOST_CONTRACT_OLDOF}, and
+all other operations of this library that accept a pointer to
+@RefClass{boost::contract::virtual_}.
+A part from that, this class is not intended to be directly used by programmers
+(and that is why this class does not have any public member and it is not
+copyable).
+
+@see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions},
+ @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+*/
+class virtual_ { // Non-copyable (see below) to avoid copy queue, stack, etc.
+/** @cond */
+private: // No public API (so users cannot use it directly by mistake).
+
+ // No boost::noncopyable to avoid its overhead when contracts disabled.
+ virtual_(virtual_&);
+ virtual_& operator=(virtual_&);
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ enum action_enum {
+ // virtual_ always held/passed as ptr so nullptr used for user call.
+ no_action,
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ check_entry_inv,
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ check_pre,
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ check_exit_inv,
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ // For outside .old(...).
+ push_old_init_copy,
+ // pop_old_init_copy as static function below.
+ // For inside .old(...).
+ call_old_ftor,
+ push_old_ftor_copy,
+ pop_old_ftor_copy,
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ check_post,
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ check_except,
+ #endif
+ };
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ // Not just an enum value because the logical combination of two values.
+ inline static bool pop_old_init_copy(action_enum a) {
+ return
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ a == check_post
+ #endif
+ #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
+ !defined(BOOST_CONTRACT_NO_EXCEPTS)
+ ||
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ a == check_except
+ #endif
+ ;
+ }
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ explicit virtual_(action_enum a) :
+ action_(a)
+ , failed_(false)
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ , result_type_name_()
+ , result_optional_()
+ #endif
+ {}
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ action_enum action_;
+ bool failed_;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ std::queue<boost::shared_ptr<void> > old_init_copies_;
+ std::queue<boost::shared_ptr<void> > old_ftor_copies_;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ boost::any result_ptr_; // Result for virtual and overriding functions.
+ char const* result_type_name_;
+ bool result_optional_;
+ #endif
+
+ // Friends (used to limit library's public API).
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ friend bool copy_old(virtual_*);
+ friend class old_pointer;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_CONDITIONS
+ BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
+ /* is_friend = */ 1, OO, RR, FF, CC, AArgs);
+ #endif
+/** @endcond */
+};
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/destructor.hpp b/boost/contract/destructor.hpp
new file mode 100644
index 0000000000..28372c7d0b
--- /dev/null
+++ b/boost/contract/destructor.hpp
@@ -0,0 +1,107 @@
+
+#ifndef BOOST_CONTRACT_DESTRUCTOR_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Program contracts for destructors.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/specify.hpp>
+#include <boost/contract/core/access.hpp>
+#if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/operation/destructor.hpp>
+#endif
+
+namespace boost { namespace contract {
+
+/**
+Program contracts for destructors.
+
+This is used to specify postconditions, exception guarantees, old value copies
+at body, and check class invariants for destructors (destructors cannot not have
+preconditions, see
+@RefSect{contract_programming_overview.destructor_calls, Destructor Calls}):
+
+@code
+class u {
+ friend class boost::contract::access;
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+public:
+ ~u() {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::destructor(this)
+ // No `.precondition` (destructors have no preconditions).
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Destructor body.
+ }
+
+ ...
+};
+@endcode
+
+For optimization, this can be omitted for destructors that do not have
+postconditions and exception guarantees, within classes that have no invariants.
+
+@see @RefSect{tutorial.destructors, Destructors}
+
+@param obj The object @c this from the scope of the enclosing destructor
+ declaring the contract.
+ (Destructors check all class invariants, including static and
+ volatile invariants, see @RefSect{tutorial.class_invariants,
+ Class Invariants} and
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+
+@tparam Class The type of the class containing the destructor declaring the
+ contract.
+ (Usually this template parameter is automatically deduced by C++
+ and it does not need to be explicitly specified by programmers.)
+
+@return The result of this function must be explicitly assigned to a variable of
+ type @RefClass{boost::contract::check} declared locally just before the
+ code of the destructor body (otherwise this library will generate a
+ run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+*/
+template<class Class>
+specify_old_postcondition_except<> destructor(Class* obj) {
+ // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
+ #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
+ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ return specify_old_postcondition_except<>(
+ new boost::contract::detail::destructor<Class>(obj));
+ #else
+ return specify_old_postcondition_except<>();
+ #endif
+}
+
+} } // namespace
+
+#endif // #include guard
+
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
+
diff --git a/boost/contract/function.hpp b/boost/contract/function.hpp
new file mode 100644
index 0000000000..5811ff9345
--- /dev/null
+++ b/boost/contract/function.hpp
@@ -0,0 +1,89 @@
+
+#ifndef BOOST_CONTRACT_FUNCTION_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Program contracts for (non-public) functions.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/specify.hpp>
+#if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #include <boost/contract/detail/operation/function.hpp>
+#endif
+
+namespace boost { namespace contract {
+
+/**
+Program contracts for non-member, private and protected functions.
+
+This is used to specify preconditions, postconditions, exception guarantees, and
+old value copies at body for non-member, private and protected functions (these
+functions never check class invariants, see
+@RefSect{contract_programming_overview.function_calls, Function Calls}):
+
+@code
+void f(...) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body.
+}
+@endcode
+
+This can be used also to program contracts in implementation code for lambda
+functions, loops, and arbitrary blocks of code.
+For optimization, this can be omitted for code that does not have preconditions,
+postconditions, and exception guarantees.
+
+@see @RefSect{tutorial.non_member_functions, Non-Member Functions},
+ @RefSect{advanced.private_and_protected_functions,
+ Private and Protected Functions},
+ @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__,
+ Lambdas\, Loops\, Code Blocks}
+
+@return The result of this function must be explicitly assigned to a variable of
+ type @RefClass{boost::contract::check} declared locally just before the
+ function body code (otherwise this library will generate a run-time
+ error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+*/
+inline specify_precondition_old_postcondition_except<> function() {
+ // Must #if also on ..._INVARIANTS here because specify_... is generic.
+ #if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
+ !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ return specify_precondition_old_postcondition_except<>(
+ new boost::contract::detail::function());
+ #else
+ return specify_precondition_old_postcondition_except<>();
+ #endif
+}
+
+} } // namespace
+
+#endif // #include guard
+
diff --git a/boost/contract/old.hpp b/boost/contract/old.hpp
new file mode 100644
index 0000000000..652ff3993a
--- /dev/null
+++ b/boost/contract/old.hpp
@@ -0,0 +1,810 @@
+
+#ifndef BOOST_CONTRACT_OLD_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Handle old values.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/virtual.hpp>
+#ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ #include <boost/contract/detail/checking.hpp>
+#endif
+#include <boost/contract/detail/operator_safe_bool.hpp>
+#include <boost/contract/detail/declspec.hpp>
+#include <boost/contract/detail/debug.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/control/expr_iif.hpp>
+#include <boost/preprocessor/config/config.hpp>
+#include <queue>
+
+#if !BOOST_PP_VARIADICS
+
+#define BOOST_CONTRACT_OLDOF \
+BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_program_old_values
+
+#else // variadics
+
+#include <boost/preprocessor/facilities/overload.hpp>
+#include <boost/preprocessor/facilities/empty.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/config.hpp>
+
+/* PRIVATE */
+
+/** @cond */
+
+#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
+ #define BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value) /* nothing */
+#else
+ #include <boost/typeof/typeof.hpp>
+ // Explicitly force old_ptr<...> conversion to allow for C++11 auto decl.
+ #define BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value) \
+ boost::contract::old_ptr<BOOST_TYPEOF(value)>
+#endif
+
+#define BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_2( \
+ v, value) \
+ BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value)(boost::contract::make_old(v, \
+ boost::contract::copy_old(v) ? (value) : boost::contract::null_old() \
+ ))
+
+#define BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_1( \
+ value) \
+ BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value)(boost::contract::make_old( \
+ boost::contract::copy_old() ? (value) : boost::contract::null_old() \
+ ))
+
+/** @endcond */
+
+/* PUBLIC */
+
+// NOTE: Leave this #defined the same regardless of ..._NO_OLDS.
+/**
+Macro typically used to copy an old value expression and assign it to an old
+value pointer.
+
+The expression expanded by this macro should be assigned to an old value
+pointer of type @RefClass{boost::contract::old_ptr} or
+@RefClass{boost::contract::old_ptr_if_copyable}.
+This is an overloaded variadic macro and it can be used in the following
+different ways.
+
+1\. From within virtual public functions and public functions overrides:
+
+@code
+BOOST_CONTRACT_OLDOF(v, old_expr)
+@endcode
+
+2\. From all other operations:
+
+@code
+BOOST_CONTRACT_OLDOF(old_expr)
+@endcode
+
+Where:
+
+@arg <c><b>v</b></c> is the extra parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
+ from the enclosing virtual public function or public function
+ overrides declaring the contract.
+@arg <c><b>old_expr</b></c> is the expression to be evaluated and copied to
+ the old value pointer.
+ (This is not a variadic macro parameter so any comma it might contain
+ must be protected by round parenthesis,
+ <c>BOOST_CONTRACT_OLDOF(v, (old_expr))</c> will always work.)
+
+On compilers that do not support variadic macros, programmers can manually copy
+old value expressions without using this macro (see
+@RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}).
+
+@see @RefSect{tutorial.old_values, Old Values}
+*/
+#define BOOST_CONTRACT_OLDOF(...) \
+ BOOST_PP_CAT( /* CAT(..., EMTPY()) required on MSVC */ \
+ BOOST_PP_OVERLOAD( \
+ BOOST_CONTRACT_ERROR_macro_OLDOF_has_invalid_number_of_arguments_, \
+ __VA_ARGS__ \
+ )(__VA_ARGS__), \
+ BOOST_PP_EMPTY() \
+ )
+
+#endif // variadics
+
+/* CODE */
+
+namespace boost { namespace contract {
+
+/**
+Trait to check if an old value type can be copied or not.
+
+By default, this unary boolean meta-function is equivalent to
+@c boost::is_copy_constructible<T> but programmers can chose to specialize it
+for user-defined types (in general some kind of specialization is needed on
+compilers that do not support C++11, see
+<a href="http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference/is_copy_constructible.html">
+<c>boost::is_copy_constructible</c></a>):
+
+@code
+class u; // Some user-defined type.
+
+namespace boost { namespace contract {
+ template<> // Specialization.
+ struct is_old_value_copyable<u> : boost::false_type {};
+} } // namespace
+@endcode
+
+In summary, a given old value type @c T is copied only if
+@c boost::contract::is_old_value_copyable<T>::value is @c true.
+Copyable old value types are always copied using
+@c boost::contract::old_value_copy<T>.
+Non-copyable old value types generate a compile-time error when
+@c boost::contract::old_ptr<T> is dereferenced, but instead leave
+@c boost::contract::old_ptr_if_copyable<T> always null (without generating
+compile-time errors).
+
+@see @RefSect{extras.old_value_requirements__templates_,
+ Old Value Requirements}
+*/
+template<typename T>
+struct is_old_value_copyable : boost::is_copy_constructible<T> {};
+
+/** @cond */
+class old_value;
+
+template<> // Needed because `old_value` incomplete type when trait first used.
+struct is_old_value_copyable<old_value> : boost::true_type {};
+/** @endcond */
+
+/**
+Trait to copy an old value.
+
+By default, the implementation of this trait uses @c T's copy constructor to
+make one single copy of the specified @p value.
+However, programmers can specialize this trait to copy old values using
+user-specific operations different from @c T's copy constructor.
+The default implementation of this trait is equivalent to:
+
+@code
+template<typename T>
+class old_value_copy {
+public:
+ explicit old_value_copy(T const& old) :
+ old_(value) // One single copy of value using T's copy constructor.
+ {}
+
+ T const& old() const { return old_; }
+
+private:
+ T const old_; // The old value copy.
+};
+@endcode
+
+This library will instantiate and use this trait only on old value types @c T
+that are copyable (i.e., for which
+<c>boost::contract::is_old_value_copyable<T>::value</c> is @c true).
+
+@see @RefSect{extras.old_value_requirements__templates_,
+ Old Value Requirements}
+*/
+template<typename T> // Used only if is_old_value_copyable<T>.
+struct old_value_copy {
+ /**
+ Construct this object by making one single copy of the specified old value.
+
+ This is the only operation within this library that actually copies old
+ values.
+ This ensures this library makes one and only one copy of old values (if they
+ actually need to be copied).
+
+ @param old The old value to copy.
+ */
+ explicit old_value_copy(T const& old) :
+ old_(old) {} // This makes the one single copy of T.
+
+ /**
+ Return a (constant) reference to the old value that was copied.
+
+ Contract assertions should not change the state of the program so the old
+ value copy is returned as @c const (see
+ @RefSect{contract_programming_overview.constant_correctness,
+ Constant Correctness}).
+ */
+ T const& old() const { return old_; }
+
+private:
+ T const old_;
+};
+
+template<typename T>
+class old_ptr_if_copyable;
+
+/**
+Old value pointer that requires the pointed old value type to be copyable.
+
+This is set to point to an actual old value copy using either
+@RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old} (that is
+why this class does not have public non-default constructors):
+
+@code
+class u {
+public:
+ virtual void f(..., boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<old_type> old_var =
+ BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ }
+
+ ...
+};
+@endcode
+
+@see @RefSect{tutorial.old_values, Old Values}
+
+@tparam T Type of the pointed old value.
+ This type must be copyable (i.e.,
+ <c>boost::contract::is_old_value_copyable<T>::value</c> is @c true),
+ otherwise this pointer will always be null and this library will
+ generate a compile-time error when the pointer is dereferenced.
+*/
+template<typename T>
+class old_ptr { /* copyable (as *) */
+public:
+ /** Pointed old value type. */
+ typedef T element_type;
+
+ /** Construct this old value pointer as null. */
+ old_ptr() {}
+
+ /**
+ Dereference this old value pointer.
+
+ This will generate a run-time error if this pointer is null and a
+ compile-time error if the pointed type @c T is not copyable (i.e., if
+ @c boost::contract::is_old_value_copyable<T>::value is @c false).
+
+ @return The pointed old value.
+ Contract assertions should not change the state of the program so
+ this member function is @c const and it returns the old value as a
+ reference to a constant object (see
+ @RefSect{contract_programming_overview.constant_correctness,
+ Constant Correctness}).
+ */
+ T const& operator*() const {
+ BOOST_STATIC_ASSERT_MSG(
+ boost::contract::is_old_value_copyable<T>::value,
+ "old_ptr<T> requires T copyable (see is_old_value_copyable<T>), "
+ "otherwise use old_ptr_if_copyable<T>"
+ );
+ BOOST_CONTRACT_DETAIL_DEBUG(typed_copy_);
+ return typed_copy_->old();
+ }
+
+ /**
+ Structure-dereference this old value pointer.
+
+ This will generate a compile-time error if the pointed type @c T is not
+ copyable (i.e., if @c boost::contract::is_old_value_copyable<T>::value is
+ @c false).
+
+ @return A pointer to the old value (null if this old value pointer is null).
+ Contract assertions should not change the state of the program so
+ this member function is @c const and it returns the old value as a
+ constant pointer to a constant object (see
+ @RefSect{contract_programming_overview.constant_correctness,
+ Constant Correctness}).
+ */
+ T const* const operator->() const {
+ BOOST_STATIC_ASSERT_MSG(
+ boost::contract::is_old_value_copyable<T>::value,
+ "old_ptr<T> requires T copyble (see is_old_value_copyable<T>), "
+ "otherwise use old_ptr_if_copyable<T>"
+ );
+ if(typed_copy_) return &typed_copy_->old();
+ return 0;
+ }
+
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr<T>,
+ !!typed_copy_)
+ #else
+ /**
+ Check if this old value pointer is null or not.
+
+ (This is implemented using safe-bool emulation on compilers that do not
+ support C++11 explicit type conversion operators.)
+
+ @return True if this pointer is not null, false otherwise.
+ */
+ explicit operator bool() const;
+ #endif
+
+/** @cond */
+private:
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ explicit old_ptr(boost::shared_ptr<old_value_copy<T> > old)
+ : typed_copy_(old) {}
+ #endif
+
+ boost::shared_ptr<old_value_copy<T> > typed_copy_;
+
+ friend class old_pointer;
+ friend class old_ptr_if_copyable<T>;
+/** @endcond */
+};
+
+/**
+Old value pointer that does not require the pointed old value type to be
+copyable.
+
+This is set to point to an actual old value copy using either
+@RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old}:
+
+@code
+template<typename T> // Type `T` might or not be copyable.
+class u {
+public:
+ virtual void f(..., boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr_if_copyable<T> old_var =
+ BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ if(old_var) ... // Always null for non-copyable types.
+ ...
+ }
+
+ ...
+};
+@endcode
+
+@see @RefSect{extras.old_value_requirements__templates_,
+ Old Value Requirements}
+
+@tparam T Type of the pointed old value.
+ If this type is not copyable (i.e.,
+ <c>boost::contract::is_old_value_copyable<T>::value</c> is @c false),
+ this pointer will always be null (but this library will not generate a
+ compile-time error when this pointer is dereferenced).
+*/
+template<typename T>
+class old_ptr_if_copyable { /* copyable (as *) */
+public:
+ /** Pointed old value type. */
+ typedef T element_type;
+
+ /** Construct this old value pointer as null. */
+ old_ptr_if_copyable() {}
+
+ /**
+ Construct this old value pointer from an old value pointer that requires
+ the old value type to be copyable.
+
+ This constructor is implicitly called by this library when assigning an
+ object of this type using @RefMacro{BOOST_CONTRACT_OLDOF} (this constructor
+ is usually not explicitly called by user code).
+
+ @param other Old value pointer that requires the old value type to be
+ copyable.
+ */
+ /* implicit */ old_ptr_if_copyable(old_ptr<T> const& other) :
+ typed_copy_(other.typed_copy_) {}
+
+ /**
+ Dereference this old value pointer.
+
+ This will generate a run-time error if this pointer is null, but no
+ compile-time error is generated if the pointed type @c T is not copyable
+ (i.e., if @c boost::contract::is_old_value_copyable<T>::value is @c false).
+
+ @return The pointed old value.
+ Contract assertions should not change the state of the program so
+ this member function is @c const and it returns the old value as a
+ reference to a constant object (see
+ @RefSect{contract_programming_overview.constant_correctness,
+ Constant Correctness}).
+ */
+ T const& operator*() const {
+ BOOST_CONTRACT_DETAIL_DEBUG(typed_copy_);
+ return typed_copy_->old();
+ }
+
+ /**
+ Structure-dereference this old value pointer.
+
+ This will return null but will not generate a compile-time error if the
+ pointed type @c T is not copyable (i.e., if
+ @c boost::contract::is_old_value_copyable<T>::value is @c false).
+
+ @return A pointer to the old value (null if this old value pointer is null).
+ Contract assertions should not change the state of the program so
+ this member function is @c const and it returns the old value as a
+ constant pointer to a constant object (see
+ @RefSect{contract_programming_overview.constant_correctness,
+ Constant Correctness}).
+ */
+ T const* const operator->() const {
+ if(typed_copy_) return &typed_copy_->old();
+ return 0;
+ }
+
+ #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
+ BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_if_copyable<T>,
+ !!typed_copy_)
+ #else
+ /**
+ Check if this old value pointer is null or not (safe-bool operator).
+
+ (This is implemented using safe-bool emulation on compilers that do not
+ support C++11 explicit type conversion operators.)
+
+ @return True if this pointer is not null, false otherwise.
+ */
+ explicit operator bool() const;
+ #endif
+
+/** @cond */
+private:
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ explicit old_ptr_if_copyable(boost::shared_ptr<old_value_copy<T> > old)
+ : typed_copy_(old) {}
+ #endif
+
+ boost::shared_ptr<old_value_copy<T> > typed_copy_;
+
+ friend class old_pointer;
+/** @endcond */
+};
+
+/**
+Convert user-specified expressions to old values.
+
+This class is often only implicitly used by this library and it does not
+explicitly appear in user code.
+
+On older compilers that cannot correctly deduce the
+@c boost::contract::is_old_value_copyable trait, programmers can manually
+specialize that trait to make sure that only old value types that are copyable
+are actually copied.
+
+@see @RefSect{extras.old_value_requirements__templates_,
+ Old Value Requirements}
+*/
+class old_value { // Copyable (as *).
+public:
+ // Following implicitly called by ternary operator `... ? ... : null_old()`.
+
+ /**
+ Construct this object from the specified old value when the old value type
+ is copy constructible.
+
+ The specified old value is copied (one time only) using
+ @c boost::contract::old_value_copy, in which case related old value pointer
+ will not be null (no copy is made if postconditions and exception guarantees
+ are not being checked, see @RefMacro{BOOST_CONTRACT_NO_OLDS}).
+
+ @param old Old value to be copied.
+
+ @tparam T Old value type.
+ */
+ template<typename T>
+ /* implicit */ old_value(
+ T const& old,
+ typename boost::enable_if<boost::contract::is_old_value_copyable<T>
+ >::type* = 0
+ )
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ : untyped_copy_(new old_value_copy<T>(old))
+ #endif // Else, leave ptr_ null (thus no copy of T).
+ {}
+
+ /**
+ Construct this object from the specified old value when the old value type
+ is not copyable.
+
+ The specified old value cannot be copied in this case so it is not copied
+ and the related old value pointer will always be null (thus a call to this
+ constructor has no effect and it will likely be optimized away by most
+ compilers).
+
+ @param old Old value (that will not be copied in this case).
+
+ @tparam T Old value type.
+ */
+ template<typename T>
+ /* implicit */ old_value(
+ T const& old,
+ typename boost::disable_if<boost::contract::is_old_value_copyable<T>
+ >::type* = 0
+ ) {} // Leave ptr_ null (thus no copy of T).
+
+/** @cond */
+private:
+ explicit old_value() {}
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ boost::shared_ptr<void> untyped_copy_; // Type erasure.
+ #endif
+
+ friend class old_pointer;
+ friend BOOST_CONTRACT_DETAIL_DECLSPEC old_value null_old();
+/** @endcond */
+};
+
+/**
+Convert old value copies to old value pointers.
+
+This class is often only implicitly used by this library and it does not
+explicitly appear in user code (that is why this class does not have public
+constructors, etc.).
+*/
+class old_pointer { // Copyable (as *).
+public:
+ /**
+ Convert this object to an actual old value pointer for which the old value
+ type @c T might or not be copyable.
+
+ For example, this is implicitly called when assigning or initializing old
+ value pointers.
+
+ @tparam T Type of the pointed old value.
+ The old value pointer will always be null if this type is not
+ copyable (see
+ @c boost::contract::is_old_value_copyable), but this library
+ will not generate a compile-time error.
+ */
+ template<typename T>
+ /* implicit */ operator old_ptr_if_copyable<T>() {
+ return get<old_ptr_if_copyable<T> >();
+ }
+
+ /**
+ Convert this object to an actual old value pointer for which the old value
+ type @c T must be copyable.
+
+ For example, this is implicitly called when assigning or initializing old
+ value pointers.
+
+ @tparam T Type of the pointed old value. This type must be copyable
+ (see @c boost::contract::is_old_value_copyable),
+ otherwise this library will generate a compile-time error when
+ the old value pointer is dereferenced.
+ */
+ template<typename T>
+ /* implicit */ operator old_ptr<T>() {
+ return get<old_ptr<T> >();
+ }
+
+/** @cond */
+private:
+ explicit old_pointer(virtual_* v, old_value const& old)
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ : v_(v), untyped_copy_(old.untyped_copy_)
+ #endif
+ {}
+
+ template<typename Ptr>
+ Ptr get() {
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ if(!boost::contract::is_old_value_copyable<typename
+ Ptr::element_type>::value) {
+ BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_);
+ return Ptr(); // Non-copyable so no old value and return null.
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ } else if(!v_ && boost::contract::detail::checking::already()) {
+ return Ptr(); // Not checking (so return null).
+ #endif
+ } else if(!v_) {
+ BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy_);
+ typedef old_value_copy<typename Ptr::element_type> copied_type;
+ boost::shared_ptr<copied_type> typed_copy = // Un-erase type.
+ boost::static_pointer_cast<copied_type>(untyped_copy_);
+ BOOST_CONTRACT_DETAIL_DEBUG(typed_copy);
+ return Ptr(typed_copy);
+ } else if(
+ v_->action_ == boost::contract::virtual_::push_old_init_copy ||
+ v_->action_ == boost::contract::virtual_::push_old_ftor_copy
+ ) {
+ BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy_);
+ std::queue<boost::shared_ptr<void> >& copies = v_->action_ ==
+ boost::contract::virtual_::push_old_ftor_copy ?
+ v_->old_ftor_copies_
+ :
+ v_->old_init_copies_
+ ;
+ copies.push(untyped_copy_);
+ return Ptr(); // Pushed (so return null).
+ } else if(
+ boost::contract::virtual_::pop_old_init_copy(v_->action_) ||
+ v_->action_ == boost::contract::virtual_::pop_old_ftor_copy
+ ) {
+ // Copy not null, but still pop it from the queue.
+ BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_);
+
+ std::queue<boost::shared_ptr<void> >& copies = v_->action_ ==
+ boost::contract::virtual_::pop_old_ftor_copy ?
+ v_->old_ftor_copies_
+ :
+ v_->old_init_copies_
+ ;
+ boost::shared_ptr<void> untyped_copy = copies.front();
+ BOOST_CONTRACT_DETAIL_DEBUG(untyped_copy);
+ copies.pop();
+
+ typedef old_value_copy<typename Ptr::element_type> copied_type;
+ boost::shared_ptr<copied_type> typed_copy = // Un-erase type.
+ boost::static_pointer_cast<copied_type>(untyped_copy);
+ BOOST_CONTRACT_DETAIL_DEBUG(typed_copy);
+ return Ptr(typed_copy);
+ }
+ BOOST_CONTRACT_DETAIL_DEBUG(!untyped_copy_);
+ #endif
+ return Ptr();
+ }
+
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ virtual_* v_;
+ boost::shared_ptr<void> untyped_copy_; // Type erasure.
+ #endif
+
+ friend BOOST_CONTRACT_DETAIL_DECLSPEC
+ old_pointer make_old(old_value const&);
+
+ friend BOOST_CONTRACT_DETAIL_DECLSPEC
+ old_pointer make_old(virtual_*, old_value const&);
+/** @endcond */
+};
+
+/**
+Return a null old value.
+
+The related old value pointer will also be null.
+This function is often only used by the code expanded by
+@RefMacro{BOOST_CONTRACT_OLDOF}.
+
+@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+
+@return Null old value.
+*/
+/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
+old_value null_old();
+
+/**
+Make an old value pointer (but not for virtual public functions and public
+functions overrides).
+
+The related old value pointer will not be null if the specified old value was
+actually copied.
+This function is often only used by code expanded by
+@c BOOST_CONTRACT_OLDOF(old_expr):
+
+@code
+boost::contract::make_old(boost::contract::copy_old() ? old_expr :
+ boost::contract::null_old())
+@endcode
+
+@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+
+@param old Old value which is usually implicitly constructed from the user old
+ value expression to be copied (use the ternary operator <c>?:</c>
+ to avoid evaluating the old value expression all together when
+ @c boost::contract::copy_old() is @c false).
+
+@return Old value pointer (usually implicitly converted to either
+ @RefClass{boost::contract::old_ptr} or
+ @RefClass{boost::contract::old_ptr_if_copyable} in user code).
+*/
+/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
+old_pointer make_old(old_value const& old);
+
+/**
+Make an old value pointer (for virtual public functions and public functions
+overrides).
+
+The related old value pointer will not be null if the specified old value was
+actually copied.
+This function is often only used by code expanded by
+@c BOOST_CONTRACT_OLDOF(v, old_expr):
+
+@code
+boost::contract::make_old(v, boost::contract::copy_old(v) ? old_expr :
+ boost::contract::null_old())
+@endcode
+
+@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+
+@param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
+ from the enclosing virtual or overriding public function declaring
+ the contract.
+@param old Old value which is usually implicitly constructed from the user old
+ value expression to be copied (use the ternary operator <c>?:</c>
+ to avoid evaluating the old value expression all together when
+ @c boost::contract::copy_old(v) is @c false).
+
+@return Old value pointer (usually implicitly converted to either
+ @RefClass{boost::contract::old_ptr} or
+ @RefClass{boost::contract::old_ptr_if_copyable} in user code).
+*/
+/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
+old_pointer make_old(virtual_* v, old_value const& old);
+
+/**
+Check if old values need to be copied (but not for virtual public functions and
+public function overrides).
+
+For example, this function always returns false when both postconditions and
+exception guarantees are not being checked (see
+@RefMacro{BOOST_CONTRACT_NO_OLDS}).
+This function is often only used by the code expanded by
+@RefMacro{BOOST_CONTRACT_OLDOF}.
+
+@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+
+@return True if old values need to be copied, false otherwise.
+*/
+inline bool copy_old() {
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ return !boost::contract::detail::checking::already();
+ #else
+ return true;
+ #endif
+ #else
+ return false; // No post checking, so never copy old values.
+ #endif
+}
+
+/**
+Check if old values need to be copied (for virtual public functions and public
+function overrides).
+
+For example, this function always returns false when both postconditions and
+exception guarantees are not being checked (see
+@RefMacro{BOOST_CONTRACT_NO_OLDS}).
+In addition, this function returns false when overridden functions are being
+called subsequent times by this library to support subcontracting.
+This function is often only used by the code expanded by
+@RefMacro{BOOST_CONTRACT_OLDOF}.
+
+@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}
+
+@param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
+ from the enclosing virtual or overriding public function declaring
+ the contract.
+
+@return True if old values need to be copied, false otherwise.
+*/
+inline bool copy_old(virtual_* v) {
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ if(!v) {
+ #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
+ return !boost::contract::detail::checking::already();
+ #else
+ return true;
+ #endif
+ }
+ return v->action_ == boost::contract::virtual_::push_old_init_copy ||
+ v->action_ == boost::contract::virtual_::push_old_ftor_copy;
+ #else
+ return false; // No post checking, so never copy old values.
+ #endif
+}
+
+} } // namespace
+
+#ifdef BOOST_CONTRACT_HEADER_ONLY
+ #include <boost/contract/detail/inlined/old.hpp>
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/override.hpp b/boost/contract/override.hpp
new file mode 100644
index 0000000000..96a4ceafbc
--- /dev/null
+++ b/boost/contract/override.hpp
@@ -0,0 +1,184 @@
+
+#ifndef BOOST_CONTRACT_OVERRIDE_HPP_
+#define BOOST_CONTRACT_OVERRIDE_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
+
+/** @file
+Handle public function overrides (for subcontracting).
+*/
+
+// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
+#include <boost/contract/core/config.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/config/config.hpp>
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Declare an override type with an arbitrary name.
+
+ Declare the override type to pass as an explicit template parameter to
+ @RefFunc{boost::contract::public_function} for public function overrides.
+
+ @see @RefSect{advanced.named_overrides, Named Overrides}
+
+ @param type_name Name of the override type this macro will declare.
+ (This is not a variadic macro parameter but it should
+ never contain commas because it is an identifier.)
+ @param func_name Function name of the public function override.
+ This macro is called just once even if the function name
+ is overloaded (the same override type is used for all
+ overloaded functions with the same name, see
+ @RefSect{advanced.function_overloads,
+ Function Overloads}).
+ (This is not a variadic macro parameter but it should
+ never contain commas because it is an identifier.)
+ */
+ #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name)
+#elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
+ #include <boost/contract/core/virtual.hpp>
+ #include <boost/contract/detail/type_traits/mirror.hpp>
+ #include <boost/contract/detail/tvariadic.hpp>
+ #include <boost/contract/detail/none.hpp>
+ #include <boost/contract/detail/name.hpp>
+
+ /* PRIVATE */
+
+ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, arity_compl, \
+ func_name) \
+ template< \
+ class BOOST_CONTRACT_DETAIL_NAME1(B), \
+ class BOOST_CONTRACT_DETAIL_NAME1(C) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, \
+ BOOST_CONTRACT_DETAIL_NAME1(Args)) \
+ > \
+ static void BOOST_CONTRACT_DETAIL_NAME1(call_base)( \
+ boost::contract::virtual_* BOOST_CONTRACT_DETAIL_NAME1(v), \
+ BOOST_CONTRACT_DETAIL_NAME1(C)* BOOST_CONTRACT_DETAIL_NAME1(obj) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, \
+ BOOST_CONTRACT_DETAIL_NAME1(Args), \
+ &, \
+ BOOST_CONTRACT_DETAIL_NAME1(args) \
+ ) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
+ boost::contract::detail::none&) \
+ ) { \
+ BOOST_CONTRACT_DETAIL_NAME1(obj)-> \
+ BOOST_CONTRACT_DETAIL_NAME1(B)::func_name( \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, \
+ BOOST_CONTRACT_DETAIL_NAME1(args)) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_NAME1(v) \
+ ); \
+ }
+
+ #if BOOST_CONTRACT_DETAIL_TVARIADIC
+ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
+ BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, func_name)
+ #else
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+
+ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
+ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
+ BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, func_name) \
+
+ #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, func_name) \
+ BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, \
+ BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), func_name)
+ #endif
+
+ /* PUBLIC */
+
+ #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
+ struct type_name { \
+ BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \
+ BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \
+ func_name \
+ ) \
+ BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
+ };
+#else
+ #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
+ struct type_name {}; /* empty (not used), just to compile */
+#endif
+
+/* PUBLIC */
+
+/**
+Declare an override type named <c>override_<i>func_name</i></c>.
+
+Declare the override type to pass as an explicit template parameter to
+@RefFunc{boost::contract::public_function} for public function overrides.
+
+@see @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+
+@param func_name Function name of the public function override.
+ This macro is called just once even if the function name is
+ overloaded (the same override type is used for all
+ overloaded functions with the same name, see
+ @RefSect{advanced.function_overloads, Function Overloads}).
+ (This is not a variadic macro parameter but it should never
+ contain any comma because it is an identifier.)
+*/
+#define BOOST_CONTRACT_OVERRIDE(func_name) \
+ BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, func_name), func_name)
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Declare multiple override types at once naming them <c>override_...</c> (for
+ convenience).
+
+ This variadic macro is provided for convenience only,
+ <c>BOOST_CONTRACT_OVERRIDES(f_1, f_2, ..., f_n)</c> expands to code
+ equivalent to:
+
+ @code
+ BOOST_CONTRACT_OVERRIDE(f_1)
+ BOOST_CONTRACT_OVERRIDE(f_2)
+ ...
+ BOOST_CONTRACT_OVERRIDE(f_n)
+ @endcode
+
+ On compilers that do not support variadic macros,
+ the override types can be equivalently programmed one-by-one calling
+ @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name as shown above.
+
+ @see @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+
+ @param ... A comma separated list of one or more function names of public
+ function overrides.
+ (Each function name should never contain commas because it is an
+ identifier.)
+ */
+ #define BOOST_CONTRACT_OVERRIDES(...)
+#elif BOOST_PP_VARIADICS
+ #include <boost/preprocessor/seq/for_each.hpp>
+ #include <boost/preprocessor/variadic/to_seq.hpp>
+
+ /* PRIVATE */
+
+ #define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, func_name) \
+ BOOST_CONTRACT_OVERRIDE(func_name)
+
+ /* PUBLIC */
+
+ #define BOOST_CONTRACT_OVERRIDES(...) \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \
+ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
+#else
+ #define BOOST_CONTRACT_OVERRIDES \
+BOOST_CONTRACT_ERROR_macro_OVERRIDES_requires_variadic_macros_otherwise_manually_repeat_OVERRIDE_macro
+#endif
+
+#endif // #include guard
+
diff --git a/boost/contract/public_function.hpp b/boost/contract/public_function.hpp
new file mode 100644
index 0000000000..f66e666cb9
--- /dev/null
+++ b/boost/contract/public_function.hpp
@@ -0,0 +1,876 @@
+
+#ifndef BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
+#define BOOST_CONTRACT_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
+
+/** @file
+Program contracts for public functions (including subcontracting).
+Overloads handle public functions that are static, virtual void, virtual non-void, overriding void, and overriding non-void.
+*/
+
+#include <boost/contract/core/config.hpp>
+#include <boost/contract/core/specify.hpp>
+#include <boost/contract/core/access.hpp>
+#include <boost/contract/core/virtual.hpp>
+/** @cond */
+// Needed within macro expansions below instead of defined(...) (PRIVATE macro).
+#if !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) || \
+ defined(BOOST_CONTRACT_STATIC_LINK)
+ #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 1
+#else
+ #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 0
+#endif
+/** @endcond */
+#include <boost/contract/detail/decl.hpp>
+#include <boost/contract/detail/tvariadic.hpp>
+#if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
+ #include <boost/contract/detail/operation/static_public_function.hpp>
+ #include <boost/contract/detail/operation/public_function.hpp>
+ #include <boost/contract/detail/type_traits/optional.hpp>
+ #include <boost/contract/detail/none.hpp>
+ #include <boost/function_types/result_type.hpp>
+ #include <boost/function_types/function_arity.hpp>
+ #include <boost/optional.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/type_traits/is_same.hpp>
+ #include <boost/static_assert.hpp>
+ #include <boost/preprocessor/tuple/eat.hpp>
+#endif
+#if !BOOST_CONTRACT_DETAIL_TVARIADIC
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/arithmetic/sub.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>
+
+namespace boost { namespace contract {
+
+// NOTE: Override and (optionally) VirtualResult allowed only when v is present
+// because:
+// * An overriding func must override a base func declared virtual so with
+// v extra param, thus the overriding func must also always have v (i.e.,
+// Override might be present only if v is also present). However, the first
+// appearing virtual func (e.g., in root class) will not override any
+// previously declared virtual func so does not need Override (i.e., Override
+// always optional).
+// Furthermore, F needs to be specified only together with Override.
+// * VirtualResult is only used for virtual functions (i.e., VirtualResult might
+// be present only if v is also present).
+// However, VirtualResult is never specified, not even for virtual functions,
+// when the return type is void (i.e., VirtualResult always optional).
+
+/**
+Program contracts for static public functions.
+
+This is used to specify preconditions, postconditions, exception guarantees, old
+value copies at body, and check static class invariants for static public
+functions:
+
+@code
+class u {
+ friend class boost::contract::access;
+
+ static void static_invariant() { // Optional (as for non-static).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+public:
+ static void f(...) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function<u>()
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body.
+ }
+
+ ...
+};
+@endcode
+
+For optimization, this can be omitted for static public functions that do not
+have preconditions, postconditions and exception guarantees, within classes that
+have no static invariants.
+
+@see @RefSect{tutorial.static_public_functions, Static Public Functions}
+
+@tparam Class The type of the class containing the static public function
+ declaring the contract.
+ This template parameter must be explicitly specified for static
+ public functions (because they have no object @c this so there
+ is no function argument from which this type template parameter
+ can be deduced by this library).
+
+@return The result of this function must be explicitly assigned to a variable of
+ type @RefClass{boost::contract::check} declared locally just before the
+ code of the static function body (otherwise this library will generate a
+ run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+*/
+template<class Class>
+specify_precondition_old_postcondition_except<> public_function() {
+ #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
+ return specify_precondition_old_postcondition_except<>(
+ new boost::contract::detail::static_public_function<Class>());
+ #else
+ return specify_precondition_old_postcondition_except<>();
+ #endif
+}
+
+/**
+Program contracts for public functions that are not static, not virtual, and do
+not not override.
+
+This is used to specify preconditions, postconditions, exception guarantees, old
+value copies at body, and check class invariants for public functions that are
+not static, not virtual, and do not override:
+
+@code
+class u {
+ friend class boost::contract::access;
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+public:
+ void f(...) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function(this)
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body.
+ }
+
+ ...
+};
+@endcode
+
+For optimization, this can be omitted for public functions that do not have
+preconditions, postconditions and exception guarantees, within classes that have
+no invariants.
+
+@see @RefSect{tutorial.public_functions, Public Functions}
+
+@param obj The object @c this from the scope of the enclosing public function
+ declaring the contract.
+ This object might be mutable, @c const, @c volatile, or
+ <c>const volatile</c> depending on the cv-qualifier of the enclosing
+ function (volatile public functions will check volatile class
+ invariants, see
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+
+@tparam Class The type of the class containing the public function declaring
+ the contract.
+ (Usually this template parameter is automatically deduced by C++
+ and it does not need to be explicitly specified by programmers.)
+
+@return The result of this function must be explicitly assigned to a variable of
+ type @RefClass{boost::contract::check} declared locally just before the
+ code of the public function body (otherwise this library will generate a
+ run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+*/
+template<class Class>
+specify_precondition_old_postcondition_except<> public_function(Class* obj) {
+ #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
+ return specify_precondition_old_postcondition_except<>(
+ new boost::contract::detail::public_function<
+ boost::contract::detail::none,
+ boost::contract::detail::none,
+ boost::contract::detail::none,
+ Class
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
+ BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
+ BOOST_CONTRACT_MAX_ARGS,
+ boost::contract::detail::none
+ )
+ >(
+ static_cast<boost::contract::virtual_*>(0),
+ obj,
+ boost::contract::detail::none::value()
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
+ BOOST_CONTRACT_MAX_ARGS)
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
+ BOOST_CONTRACT_MAX_ARGS,
+ boost::contract::detail::none::value()
+ )
+ )
+ );
+ #else
+ return specify_precondition_old_postcondition_except<>();
+ #endif
+}
+
+/** @cond */
+
+// For non-static, virtual, and non-overriding public functions (PRIVATE macro).
+#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \
+ has_virtual_result) \
+ template< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \
+ BOOST_PP_COMMA_IF(has_virtual_result) \
+ class Class \
+ > \
+ specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \
+ public_function( \
+ virtual_* v \
+ BOOST_PP_COMMA_IF(has_virtual_result) \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \
+ , Class* obj \
+ ) { \
+ BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
+ /* no F... so cannot enforce contracted F returns VirtualResult */ \
+ return (specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
+ new boost::contract::detail::public_function< \
+ boost::contract::detail::none, \
+ BOOST_PP_IIF(has_virtual_result, \
+ VirtualResult \
+ , \
+ boost::contract::detail::none \
+ ), \
+ boost::contract::detail::none, \
+ Class \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
+ BOOST_CONTRACT_MAX_ARGS) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
+ BOOST_CONTRACT_MAX_ARGS, \
+ boost::contract::detail::none \
+ ) \
+ >( \
+ v, \
+ obj, \
+ BOOST_PP_IIF(has_virtual_result, \
+ r \
+ , \
+ boost::contract::detail::none::value() \
+ ) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
+ BOOST_CONTRACT_MAX_ARGS) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
+ BOOST_CONTRACT_MAX_ARGS, \
+ boost::contract::detail::none::value() \
+ ) \
+ ) \
+ )); \
+ , \
+ return specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
+ ) \
+ }
+
+/** @endcond */
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Program contracts for void virtual public functions that do not override.
+
+ This is used to specify preconditions, postconditions, exception guarantees,
+ old value copies at body, and check class invariants for public functions
+ that are virtual, do not override, and return @c void:
+
+ @code
+ class u {
+ friend class boost::contract::access;
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ public:
+ void f(..., boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body.
+ }
+
+ ...
+ };
+ @endcode
+
+ A virtual public function should always call
+ @RefFunc{boost::contract::public_function} otherwise this library will not
+ be able to correctly use it for subcontracting.
+
+ @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
+
+ @param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value
+ @c 0 from the enclosing virtual public function.
+ @param obj The object @c this from the scope of the enclosing virtual
+ public function declaring the contract.
+ This object might be mutable, @c const, @c volatile, or
+ <c>const volatile</c> depending on the cv-qualifier of the
+ enclosing function (volatile public functions will check
+ volatile class invariants, see
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+
+ @tparam Class The type of the class containing the virtual public function
+ declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers.)
+
+ @return The result of this function must be explicitly assigned to a
+ variable of type @RefClass{boost::contract::check} declared locally
+ just before the code of the public function body (otherwise this
+ library will generate a run-time error, see
+ @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+ */
+ template<class Class>
+ specify_precondition_old_postcondition_except<> public_function(
+ virtual_* v, Class* obj);
+
+ /**
+ Program contracts for non-void virtual public functions that do not
+ override.
+
+ This is used to specify preconditions, postconditions, exception guarantees,
+ old value copies at body, and check class invariants for public functions
+ that are virtual, do not override, and do not return @c void:
+
+ @code
+ class u {
+ friend class boost::contract::access;
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ public:
+ t f(..., boost::contract::virtual_* v = 0) {
+ t result;
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function(
+ v, result, this)
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ })
+ .postcondition([&] (t const& result) { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body (use `return result = return_expr`).
+ }
+
+ ...
+ };
+ @endcode
+
+ A virtual public function should always call
+ @RefFunc{boost::contract::public_function} otherwise this library will not
+ be able to correctly use it for subcontracting.
+
+ @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
+
+ @param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value
+ @c 0 from the enclosing virtual public function.
+ @param r A reference to the return value of the enclosing virtual public
+ function declaring the contract.
+ This is usually a local variable declared by the enclosing
+ virtual public function just before the contract, but
+ programmers must set it to the actual value being returned by
+ the function at each @c return statement.
+ @param obj The object @c this from the scope of the enclosing virtual
+ public function declaring the contract.
+ This object might be mutable, @c const, @c volatile, or
+ <c>const volatile</c> depending on the cv-qualifier of the
+ enclosing function (volatile public functions will check
+ volatile class invariants, see
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+
+ @tparam VirtualResult This type must be the same as, or compatible with,
+ the return type of the enclosing virtual public
+ function declaring the contract (this library might
+ not be able to generate a compile-time error if
+ these types mismatch, but in general that will cause
+ run-time errors or undefined behaviour).
+ Alternatively,
+ <c>boost::optional<<i>return-type</i>></c> can also
+ be used (see
+ @RefSect{advanced.optional_return_values,
+ Optional Return Values}).
+ (Usually this template parameter is automatically
+ deduced by C++ and it does not need to be explicitly
+ specified by programmers.)
+ @tparam Class The type of the class containing the virtual public function
+ declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers.)
+
+ @return The result of this function must be explicitly assigned to a
+ variable of type @RefClass{boost::contract::check} declared locally
+ just before the code of the public function body (otherwise this
+ library will generate a run-time error, see
+ @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+ */
+ template<typename VirtualResult, class Class>
+ specify_precondition_old_postcondition_except<VirtualResult>
+ public_function(virtual_* v, VirtualResult& r, Class* obj);
+#else
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
+ /* has_virtual_result = */ 0)
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
+ /* has_virtual_result = */ 1)
+#endif
+
+/** @cond */
+
+// For non-static, virtual, and overriding public functions (PRIVATE macro).
+#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
+ z, arity, arity_compl, has_virtual_result) \
+ BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
+ arity, /* is_friend = */ 0, has_virtual_result, \
+ Override, VirtualResult, F, Class, Args, \
+ v, r, f, obj, args \
+ ) { \
+ BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
+ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
+ /* assert not strictly necessary as compilation will fail */ \
+ /* anyways, but helps limiting cryptic compiler's errors */ \
+ BOOST_STATIC_ASSERT_MSG( \
+ /* -2 for both `this` and `virtual_*` extra parameters */ \
+ ( \
+ boost::function_types::function_arity<F>::value - 2 \
+ == \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args) \
+ ), \
+ "missing one or more arguments for specified function" \
+ ); \
+ } \
+ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
+ /* assert consistency of F's result type and VirtualResult */ \
+ BOOST_PP_IIF(has_virtual_result, \
+ BOOST_STATIC_ASSERT_MSG \
+ , \
+ BOOST_PP_TUPLE_EAT(2) \
+ )( \
+ (boost::is_same< \
+ typename boost::remove_reference<typename boost:: \
+ function_types::result_type<F>::type>::type, \
+ typename boost::contract::detail:: \
+ remove_value_reference_if_optional< \
+ VirtualResult \
+ >::type \
+ >::value), \
+ "mismatching result type for specified function" \
+ ); \
+ } \
+ { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
+ /* assert this so lib can check and enforce override */ \
+ BOOST_STATIC_ASSERT_MSG( \
+ boost::contract::access::has_base_types<Class>::value, \
+ "enclosing class missing 'base-types' typedef" \
+ ); \
+ } \
+ return (specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
+ new boost::contract::detail::public_function< \
+ Override, \
+ BOOST_PP_IIF(has_virtual_result, \
+ VirtualResult \
+ , \
+ boost::contract::detail::none \
+ ), \
+ F, \
+ Class \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
+ boost::contract::detail::none) \
+ >( \
+ v, \
+ obj, \
+ BOOST_PP_IIF(has_virtual_result, \
+ r \
+ , \
+ boost::contract::detail::none::value() \
+ ) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
+ BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, args) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
+ BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
+ boost::contract::detail::none::value()) \
+ ) \
+ )); \
+ , \
+ return specify_precondition_old_postcondition_except< \
+ BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
+ ) \
+ }
+
+/** @endcond */
+
+#ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
+ /**
+ Program contracts for void public functions overrides (virtual or not).
+
+ This is used to specify preconditions, postconditions, exception guarantees,
+ old value copies at body, and check class invariants for public function
+ overrides (virtual or not) that return @c void:
+
+ @code
+ class u
+ #define BASES private boost::contract::constructor_precondition<u>, \
+ public b, private w
+ : BASES
+ {
+ friend class boost::contract::access;
+
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ BOOST_CONTRACT_OVERRIDES(f)
+
+ public:
+ // Override from `b::f`.
+ void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function<
+ override_f>(v, &u::f, this, a_1, ..., a_n)
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ })
+ .postcondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body.
+ }
+
+ ...
+ };
+ @endcode
+
+ A public function override should always call
+ @RefFunc{boost::contract::public_function} otherwise this library will not
+ be able to correctly use it for subcontracting.
+
+ @see @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+
+ @param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value
+ @c 0 from the enclosing public function override.
+ @param f A pointer to the enclosing public function override declaring
+ the contract.
+ @param obj The object @c this from the scope of the enclosing public
+ function override declaring the contract.
+ This object might be mutable, @c const, @c volatile, or
+ <c>const volatile</c> depending on the cv-qualifier of the
+ enclosing function (volatile public functions will check
+ volatile class invariants, see
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+ @param args All arguments passed to the enclosing public function override
+ declaring the contract (by reference and in the order they
+ appear in the enclosing function declaration), but excluding the
+ trailing argument @c v.
+
+ @tparam Override The type <c>override_<i>function-name</i></c> declared
+ using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related
+ macros.
+ This template parameter must be explicitly specified
+ (because there is no function argument from which it can
+ be automatically deduced by C++).
+ @tparam F The function pointer type of the enclosing public function
+ override declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers, but see
+ @RefSect{advanced.function_overloads, Function Overloads}.)
+ @tparam Class The type of the class containing the virtual public function
+ declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers.)
+ @tparam Args The types of all parameters passed to the enclosing public
+ function override declaring the contract, but excluding the
+ trailing parameter type <c>boost::contract::virtual_*</c>.
+ On compilers that do not support variadic templates, this
+ library internally implements this function using
+ preprocessor meta-programming (in this case, the maximum
+ number of supported arguments is defined by
+ @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
+ (Usually these template parameters are automatically deduced
+ by C++ and they do not need to be explicitly specified by
+ programmers.)
+
+ @return The result of this function must be explicitly assigned to a
+ variable of type @RefClass{boost::contract::check} declared locally
+ just before the code of the public function body (otherwise this
+ library will generate a run-time error, see
+ @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+ */
+ template<class Override, typename F, class Class, typename... Args>
+ specify_precondition_old_postcondition_except<> public_function(
+ virtual_* v, F f, Class* obj, Args&... args);
+
+ /**
+ Program contracts for non-void public functions overrides (virtual or not).
+
+ This is used to specify preconditions, postconditions, exception guarantees,
+ old value copies at body, and check class invariants for public function
+ overrides (virtual or not) that do not return @c void:
+
+ @code
+ class u
+ #define BASES private boost::contract::constructor_precondition<u>, \
+ public b, private w
+ : BASES
+ {
+ friend class boost::contract::access;
+
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ void invariant() const { // Optional (as for static and volatile).
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ }
+
+ BOOST_CONTRACT_OVERRIDES(f)
+
+ public:
+ // Override from `b::f`.
+ t f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
+ t result;
+ boost::contract::old_ptr<old_type> old_var;
+ boost::contract::check c = boost::contract::public_function<
+ override_f>(v, result, &u::f, this, a_1, ..., a_n)
+ .precondition([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .old([&] { // Optional.
+ old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
+ ...
+ })
+ .postcondition([&] (t const& result) { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ .except([&] { // Optional.
+ BOOST_CONTRACT_ASSERT(...);
+ ...
+ })
+ ;
+
+ ... // Function body (use `return result = return_expr`).
+ }
+
+ ...
+ };
+ @endcode
+
+ A public function override should always call
+ @RefFunc{boost::contract::public_function} otherwise this library will not
+ be able to correctly use it for subcontracting.
+
+ @see @RefSect{tutorial.public_function_overrides__subcontracting_,
+ Public Function Overrides}
+
+ @param v The trailing parameter of type
+ @RefClass{boost::contract::virtual_}<c>*</c> and default value
+ @c 0 from the enclosing public function override.
+ @param r A reference to the return value of the enclosing public function
+ override declaring the contract.
+ This is usually a local variable declared by the enclosing
+ public function override just before the contract, but
+ programmers must set it to the actual value being returned by
+ the function at each @c return statement.
+ @param f A pointer to the enclosing public function override declaring
+ the contract.
+ @param obj The object @c this from the scope of the enclosing public
+ function override declaring the contract.
+ This object might be mutable, @c const, @c volatile, or
+ <c>const volatile</c> depending on the cv-qualifier of the
+ enclosing function (volatile public functions will check
+ volatile class invariants, see
+ @RefSect{extras.volatile_public_functions,
+ Volatile Public Functions}).
+ @param args All arguments passed to the enclosing public function override
+ declaring the contract (by reference and in the order they
+ appear in the enclosing function declaration), but excluding the
+ trailing argument @c v.
+
+ @tparam Override The type <c>override_<i>function-name</i></c> declared
+ using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related
+ macros.
+ This template parameter must be explicitly specified
+ (because there is no function argument from which it can
+ be automatically deduced by C++).
+ @tparam VirtualResult This type must be the same as, or compatible with,
+ the return type of the enclosing public function
+ override declaring the contract (this library might
+ not be able to generate a compile-time error if
+ these types mismatch, but in general that will cause
+ run-time errors or undefined behaviour).
+ Alternatively,
+ <c>boost::optional<<i>return-type</i>></c> can also
+ be used (see
+ @RefSect{advanced.optional_return_values,
+ Optional Return Values}).
+ (Usually this template parameter is automatically
+ deduced by C++ and it does not need to be explicitly
+ specified by programmers.)
+ @tparam F The function pointer type of the enclosing public function
+ override declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers, but see
+ @RefSect{advanced.function_overloads,
+ Function Overloads}.)
+ @tparam Class The type of the class containing the virtual public function
+ declaring the contract.
+ (Usually this template parameter is automatically deduced by
+ C++ and it does not need to be explicitly specified by
+ programmers.)
+ @tparam Args The types of all parameters passed to the enclosing public
+ function override declaring the contract, but excluding the
+ trailing parameter type <c>boost::contract::virtual_*</c>.
+ On compilers that do not support variadic templates, this
+ library internally implements this function using
+ preprocessor meta-programming (in this case, the maximum
+ number of supported arguments is defined by
+ @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
+ (Usually these template parameters are automatically deduced
+ by C++ and they do not need to be explicitly specified by
+ programmers.)
+
+ @return The result of this function must be explicitly assigned to a
+ variable of type @RefClass{boost::contract::check} declared locally
+ just before the code of the public function body (otherwise this
+ library will generate a run-time error, see
+ @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
+ */
+ template<class Override, typename VirtualResult, typename F, class Class,
+ typename... Args>
+ specify_precondition_old_postcondition_except<VirtualResult>
+ public_function(virtual_* v, VirtualResult& r, F f, Class* obj,
+ Args&... args);
+
+#elif BOOST_CONTRACT_DETAIL_TVARIADIC
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
+ /* arity_compl = */ ~, /* has_virtual_result = */ 0)
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
+ /* arity_compl = */ ~, /* has_virtual_result = */ 1)
+
+#else
+ /* PRIVATE */
+
+ #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_( \
+ z, arity, unused) \
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, arity, \
+ BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), ~)
+
+ #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \
+ arity, arity_compl, unused) \
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
+ arity, arity_compl, /* has_virtual_result = */ 0) \
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
+ arity, arity_compl, /* has_virtual_result = */ 1)
+
+ /* CODE */
+
+ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
+ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_, ~)
+#endif
+
+} } // namespace
+
+#endif // #include guard
+