add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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