mirror of
https://github.com/boostorg/contract.git
synced 2026-02-27 04:52:22 +00:00
finished very first draft of reference docs
This commit is contained in:
@@ -7,9 +7,11 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Include all header files required by this library at once.
|
||||
*/
|
||||
|
||||
// Include all and only public headers as users would (not core headers, etc.).
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#include <boost/contract/assert.hpp>
|
||||
#include <boost/contract/base_types.hpp>
|
||||
#include <boost/contract/call_if.hpp>
|
||||
|
||||
@@ -7,22 +7,39 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Facilities to assert contract conditions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
// Must use ternary operator expr here (instead of if-statement) so this macro
|
||||
// can always be used with if-statements and all other C++ constructs.
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
// Ternary operator used so this macro expand to an expression and it can
|
||||
// be used with `if` and all other statements.
|
||||
#define BOOST_CONTRACT_ASSERT(condition) \
|
||||
((condition) ? (void*)0 : throw boost::contract::assertion_failure( \
|
||||
__FILE__, __LINE__, BOOST_PP_STRINGIZE(condition)))
|
||||
#else
|
||||
/**
|
||||
Preferred way to assert contract conditions.
|
||||
Any exception thrown from within a preconditions, postcondition, and
|
||||
class invariant functor is interpreted by this library as a contract
|
||||
failure. Therefore, users can program contract assertions manually throwing
|
||||
exceptions in case the asserted condition is checked to be @c false (this
|
||||
library will then call the appropriate contract failure handler).
|
||||
However, using this macro is preferred because in case @condition is
|
||||
checked to be @c false, this macro expands to code that throws
|
||||
@RefClass{boost::contract::assertion_failure} with the correct assertion
|
||||
file name (@c __FILE__), line number (@c __LINE__), and condition source
|
||||
code text that will produce an informative error message.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
@param condition The contract condition being checked.
|
||||
*/
|
||||
#define BOOST_CONTRACT_ASSERT(condition) /* nothing */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
// TODO: Document the max number of bases is 20 because of Boost.MPL vector limit. If Boost.MPL vector and related alg impl was to change to use variadic templates in the future there will be not limit to max bases (but for now this high limit is better than the extra complexity of reimpl all Boost.MPL vector, etc. within this lib with variadic templates).
|
||||
|
||||
/** @file */
|
||||
/** @file
|
||||
Facilities to specify base classes so to support subcontracting.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#include <boost/preprocessor/config/config.hpp>
|
||||
@@ -21,6 +23,18 @@ BOOST_CONTRACT_ERROR_macro_BASE_TYPES_requires_variadic_macros_otherwise_manuall
|
||||
|
||||
#elif defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
|
||||
|
||||
/**
|
||||
Variadic macro to program base classes @c typedef.
|
||||
A class that has contracts for one or more overriding public functions must
|
||||
declare a @c typedef named @RefMacro{BOOST_CONTRACT_BASE_TYPEDEF} using this
|
||||
macro.
|
||||
This @c typedef can be programmed manually without this macro on compilers that
|
||||
do not support variadic macros (see @RefSect{advanced_topics, Advanced Topics}).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param ... Comma separated list of base classes with must explicitly list their
|
||||
access (@c public, @c protected, or @c private) and @c virtual (if
|
||||
present) specifiers.
|
||||
*/
|
||||
#define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */
|
||||
|
||||
#else // contracts on
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
|
||||
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
|
||||
|
||||
/** @file
|
||||
Statically disable execution but also compilation of functor calls.
|
||||
*/
|
||||
|
||||
// Do not include all_core_headers here (call_if is essentially standalone).
|
||||
#include <boost/contract/detail/always_true.hpp>
|
||||
#include <boost/contract/detail/none.hpp>
|
||||
@@ -16,6 +20,8 @@
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
/** @cond */
|
||||
|
||||
// Boost.ResultOf not always able to deduce lambda result type (on MSVC).
|
||||
#ifndef BOOST_NO_CXX11_DECL_TYPE
|
||||
#include <boost/utility/declval.hpp>
|
||||
@@ -27,43 +33,152 @@
|
||||
typename boost::result_of<F()>::type
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/* CODE */
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
template<bool Cond, typename Then, typename R = boost::contract::detail::none>
|
||||
/**
|
||||
Unspecialized class template to control execution and compilation of functor
|
||||
calls via a static boolean condition.
|
||||
This class template has no member because it should never be used directly, it
|
||||
should only be used via its specializations.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}
|
||||
@tparam Cond Static boolean condition controlling functor calls.
|
||||
@tparam Then Type of functor to call when the static condition if true.
|
||||
@tparam R Return type of then-branch functor.
|
||||
*/
|
||||
template<bool Cond, typename Then, typename R =
|
||||
#ifndef DOXYGEN
|
||||
boost::contract::detail::none
|
||||
#else
|
||||
unspecified
|
||||
#endif
|
||||
>
|
||||
struct call_if_statement {}; // Empty so cannot be used (but copyable).
|
||||
|
||||
// Dispatch true condition (then) between non-void and void calls.
|
||||
// IMPORTANT: result_of<Then()> can be evaluated only when condition is already
|
||||
// checked to be true (as Then() is required to be valid only in that case) so
|
||||
// this extra level of dispatching is necessary to avoid compiler errors.
|
||||
/**
|
||||
Template specialization to dispatch between then-branch functor calls that
|
||||
return void and the ones that return non-void.
|
||||
@note <c>result_of<Then()></c> should be evaluated only when the static
|
||||
condition is already checked to be true (because @c Then() is
|
||||
required to compile only in that case). Thus, this template
|
||||
specialization introduces an extra level of indirectly necessary to the
|
||||
proper lazy evaluation of that result-of.
|
||||
The base class is a call-if statement so the else statement and other else-if
|
||||
can be specified if needed. Ultimately this will return the return value of the
|
||||
functor being compiled and called.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}
|
||||
@tparam Then Type of functor to call when the static condition if true.
|
||||
*/
|
||||
template<typename Then>
|
||||
struct call_if_statement<true, Then, boost::contract::detail::none> :
|
||||
call_if_statement<true, Then, // Copyable (as its base).
|
||||
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>
|
||||
{
|
||||
struct call_if_statement<true, Then,
|
||||
#ifndef DOXYGEN
|
||||
boost::contract::detail::none
|
||||
#else
|
||||
unspecified
|
||||
#endif
|
||||
> :
|
||||
call_if_statement<true, Then,
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)
|
||||
#else
|
||||
typename result_of<Then()>::type
|
||||
#endif
|
||||
>
|
||||
{ // Copyable (as its base).
|
||||
/**
|
||||
Construct this object with the then-branch functor.
|
||||
@param f Then-branch nullary functor, called or compiled in this case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
*/
|
||||
explicit call_if_statement(Then f) : call_if_statement<true, Then,
|
||||
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>(f) {}
|
||||
};
|
||||
|
||||
// True condition (then) for non-void call.
|
||||
/**
|
||||
Template specialization to handle true static conditions for then-branch functor
|
||||
calls returning non-void.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}
|
||||
@tparam Then Type of functor to call when the static condition if true.
|
||||
@tparam R Non-void return type of the then-branch functor call.
|
||||
*/
|
||||
template<typename Then, typename R>
|
||||
struct call_if_statement<true, Then, R> { // Copyable (as *).
|
||||
/**
|
||||
Construct this object with the then-branch functor.
|
||||
@param f Then-branch nullary functor, called and compiled in this case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
*/
|
||||
explicit call_if_statement(Then f) : r_(boost::make_shared<R>(f())) {}
|
||||
|
||||
operator R() const { return *r_; }
|
||||
/** Return value returned by the call to the then-branch functor. */
|
||||
operator R const&() const { return *r_; }
|
||||
|
||||
/** Return value returned by the call to the then-branch functor. */
|
||||
operator R&() { return *r_; }
|
||||
|
||||
/**
|
||||
Specify the else-branch functor.
|
||||
@param f Else-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@return Return value returned by the call to the then-branch functor.
|
||||
*/
|
||||
template<typename Else>
|
||||
R else_(Else const&) const { return *r_; }
|
||||
R const& else_(Else const& f) const { return *r_; }
|
||||
|
||||
/**
|
||||
Specify the else-branch functor.
|
||||
@param f Else-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@return Return value returned by the call to the then-branch functor.
|
||||
*/
|
||||
template<typename Else>
|
||||
R& else_(Else const& f) { return *r_; }
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam ElseIfCond Static boolean condition controlling functor calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
then-branch functor in this case.
|
||||
*/
|
||||
template<bool ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<true, Then, R> else_if_c(ElseIfThen const&) const {
|
||||
call_if_statement<true, Then, R> else_if_c(ElseIfThen const& f) const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam ElseIfCond Static boolean nullary meta-function controlling functor
|
||||
calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
then-branch functor in this case.
|
||||
*/
|
||||
template<class ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<true, Then, R> else_if(ElseIfThen const&) const {
|
||||
call_if_statement<true, Then, R> else_if(ElseIfThen const& f) const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -71,45 +186,149 @@ private:
|
||||
boost::shared_ptr<R> r_;
|
||||
};
|
||||
|
||||
// True condition (then) for void call.
|
||||
/**
|
||||
Template specialization to handle true static conditions for then-branch functor
|
||||
calls returning void.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}
|
||||
@tparam Then Type of functor to call when the static condition if true.
|
||||
*/
|
||||
template<typename Then>
|
||||
struct call_if_statement<true, Then, void> { // Copyable (no data).
|
||||
/**
|
||||
Construct this object with the then-branch functor.
|
||||
@param f Then-branch nullary functor, called and compiled in this case.
|
||||
The return type of this functor as well as of all other
|
||||
specified functors for the call-if object must be @c void in
|
||||
this case.
|
||||
*/
|
||||
explicit call_if_statement(Then f) { f(); }
|
||||
|
||||
// Cannot provide `operator R()` here, because R is void.
|
||||
|
||||
/**
|
||||
Specify the else-branch functor.
|
||||
@param f Else-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor as well as of all other
|
||||
specified functors for the call-if object must be @c void in
|
||||
this case.
|
||||
*/
|
||||
template<typename Else>
|
||||
void else_(Else const&) const {}
|
||||
void else_(Else const& f) const {}
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor as well as of all other
|
||||
specified functors for the call-if object must be @c void in
|
||||
this case.
|
||||
@tparam ElseIfCond Static boolean condition controlling functor calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately @c void will be returned in this
|
||||
case.
|
||||
*/
|
||||
template<bool ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<true, Then, void> else_if_c(ElseIfThen const&) const {
|
||||
call_if_statement<true, Then, void> else_if_c(ElseIfThen const& f) const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor as well as of all other
|
||||
specified functors for the call-if object must be @c void in
|
||||
this case.
|
||||
@tparam ElseIfCond Static boolean nullary meta-function controlling functor
|
||||
calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately @c void will be returned in this
|
||||
case.
|
||||
*/
|
||||
template<class ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<true, Then, void> else_if(ElseIfThen const&) const {
|
||||
call_if_statement<true, Then, void> else_if(ElseIfThen const& f) const {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// False condition (else) for both non-void and void calls.
|
||||
/**
|
||||
Template specialization to handle false static conditions.
|
||||
This single specialization can handle both else-branch functor calls that
|
||||
return void and that return non-void.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}
|
||||
@tparam Then Type of functor to call when the static condition if true.
|
||||
*/
|
||||
template<typename Then> // Copyable (no data).
|
||||
struct call_if_statement<false, Then, boost::contract::detail::none> {
|
||||
explicit call_if_statement(Then const&) {}
|
||||
struct call_if_statement<false, Then,
|
||||
#ifndef DOXYGEN
|
||||
boost::contract::detail::none
|
||||
#else
|
||||
unspecified
|
||||
#endif
|
||||
> {
|
||||
/**
|
||||
Construct this object with the then-branch functor.
|
||||
@param f Then-branch nullary functor, never called or compiled in this
|
||||
case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
*/
|
||||
explicit call_if_statement(Then const& f) {}
|
||||
|
||||
// Do not provide `operator result_type()` here, require else_ instead.
|
||||
|
||||
// IMPORTANT: result_of<Else()> can be evaluated only when condition is
|
||||
// already checked to be false (as Else() is required to be valid only in
|
||||
// that case) so this is done lazily only in this template instantiation.
|
||||
/**
|
||||
Specify the else-branch functor.
|
||||
@note <c>result_of<Else()></c> should be evaluated only when the static
|
||||
condition is already checked to be false (because @c Else() is
|
||||
required to compile only in that case). Thus, that result-of is
|
||||
evaluate lazily only in this template instantiation.
|
||||
@param f Else-branch nullary functor, called and compiled in this case.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@return The return value of the call to the else-branch functor.
|
||||
*/
|
||||
template<typename Else>
|
||||
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Else) else_(Else f) const { return f(); }
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Else)
|
||||
#else
|
||||
typename result_of<Else()>::type
|
||||
#endif
|
||||
else_(Else f) const { return f(); }
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, called and compiled if and only
|
||||
if @c ElseIfCond is @c true.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam ElseIfCond Static boolean condition controlling functor calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
functor call being compiled and executed.
|
||||
*/
|
||||
template<bool ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<ElseIfCond, ElseIfThen> else_if_c(ElseIfThen f) const {
|
||||
return call_if_statement<ElseIfCond, ElseIfThen>(f);
|
||||
}
|
||||
|
||||
/**
|
||||
Specify an else-if-branch functor.
|
||||
@param f Else-if-branch nullary functor, called and compiled if and only
|
||||
if @c ElseIfCond::value is @c true.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam ElseIfCond Static boolean nullary meta-function controlling functor
|
||||
calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
functor call being compiled and executed.
|
||||
*/
|
||||
template<class ElseIfCond, typename ElseIfThen>
|
||||
call_if_statement<ElseIfCond::value, ElseIfThen> else_if(ElseIfThen f)
|
||||
const {
|
||||
@@ -117,22 +336,64 @@ struct call_if_statement<false, Then, boost::contract::detail::none> {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Make a call-if object with the specified then-branch functor
|
||||
@param f Then-branch nullary functor, called and compiled if and only if
|
||||
@c Cond if @c true.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam Cond Static boolean condition controlling functor compilation and calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
functor call being compiled and executed.
|
||||
*/
|
||||
template<bool Cond, typename Then>
|
||||
call_if_statement<Cond, Then> call_if_c(Then f) {
|
||||
return call_if_statement<Cond, Then>(f);
|
||||
}
|
||||
|
||||
/**
|
||||
Make a call-if object with the specified then-branch functor
|
||||
@param f Then-branch nullary functor, called and compiled if and only if
|
||||
@c Cond::value if @c true.
|
||||
The return type of this functor must be the same or implicitly
|
||||
convertible into the return type of all other functors specified
|
||||
for the call-if object.
|
||||
@tparam Cond Static boolean nullary meta-function controlling functor calls.
|
||||
@return The call-if statement so the else statement and other else-if can be
|
||||
specified if needed. Ultimately will return the return value of the
|
||||
functor call being compiled and executed.
|
||||
*/
|
||||
template<class Cond, typename Then>
|
||||
call_if_statement<Cond::value, Then> call_if(Then f) {
|
||||
return call_if_statement<Cond::value, Then>(f);
|
||||
}
|
||||
|
||||
/**
|
||||
Return value of specified functor call if and only if specified static condition
|
||||
is true, otherwise return true.
|
||||
@param f Nullary boolean functor to call and compile if and only if @c Cond
|
||||
is @c true.
|
||||
@tparam Cond Static boolean condition controlling functor compilation and call.
|
||||
@return Boolean value returned by @c f() if static condition if true, otherwise
|
||||
simply return @c true (i.e., check trivially passed).
|
||||
*/
|
||||
template<bool Cond, typename F>
|
||||
bool check_if_c(F f) {
|
||||
return call_if_c<Cond>(f).else_(
|
||||
boost::contract::detail::always_true());
|
||||
}
|
||||
|
||||
/**
|
||||
Return value of specified functor call if and only if specified static condition
|
||||
is true, otherwise return true.
|
||||
@param f Nullary boolean functor to call and compile if and only if
|
||||
@c Cond::value is @c true.
|
||||
@tparam Cond Static boolean nullary meta-function controlling functor calls.
|
||||
@return Boolean value returned by @c f() if static condition if true, otherwise
|
||||
simply return @c true (i.e., check trivially passed).
|
||||
*/
|
||||
template<class Cond, typename F>
|
||||
bool check_if(F f) {
|
||||
return call_if_c<Cond::value>(f).else_(
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Program contracts for constructors.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
|
||||
@@ -20,6 +22,17 @@
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
Program contracts for constructors.
|
||||
This is used to specify postconditions and check class invariants for
|
||||
constructors (see @RefClass{boost::contract::constructor_precondition} to
|
||||
specify preconditions for constructors instead).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param obj The object @c this in scope of the constructor being contracted.
|
||||
@return The result of this function must be assigned to variable of type
|
||||
@RefClass{boost::contract::guard} declared locally within the
|
||||
constructor being contracted.
|
||||
*/
|
||||
template<class C>
|
||||
set_old_postcondition<> constructor(C* obj) {
|
||||
// Must #if also on ..._PRECONDITIONS here because set_... is generic.
|
||||
@@ -33,17 +46,42 @@ set_old_postcondition<> constructor(C* obj) {
|
||||
}
|
||||
|
||||
// TODO: Document that constructor_precondition for unions must be called at the very beginning of ctor body before `boost::contract::guard c = ...` (because unions cannot have base classes, not even in C++11).
|
||||
template<class C> // tparam avoids multiple instance of same base in user code.
|
||||
/**
|
||||
Program constructor preconditions.
|
||||
This class must be the very first base class of the class being contracted. Also
|
||||
the contracted class must privately inherit from this base class.
|
||||
|
||||
Unions cannot have base classes so this class can be used to declare a local
|
||||
object within the constructor function just before
|
||||
@RefClass{boost::contract::constructor} is used (see
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@tparam C Class of constructor being contracted (CRTP used here to avoid
|
||||
multiple instances of same base class error).
|
||||
*/
|
||||
template<class C>
|
||||
class constructor_precondition { // Copyable (no data).
|
||||
public:
|
||||
constructor_precondition() {} // For user ctor overloads with no pre.
|
||||
/** Construct this object for constructor that do not have preconditions. */
|
||||
constructor_precondition() {}
|
||||
|
||||
/**
|
||||
Constructor this object specifying constructor preconditions.
|
||||
@param f Functor called by this library to check preconditions. Any
|
||||
exception thrown by a call to this functor indicates a
|
||||
precondition failure. Assertions within this functor are usually
|
||||
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}. This functor
|
||||
must be a nullary functor. This functor could capture variables
|
||||
by value, or better by (constant) reference to void extra
|
||||
copies.
|
||||
*/
|
||||
template<typename F>
|
||||
explicit constructor_precondition(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
if(boost::contract::detail::check_guard::checking()) return;
|
||||
try {
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NOTHING
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
|
||||
boost::contract::detail::check_guard checking;
|
||||
#endif
|
||||
f();
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
// 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
|
||||
Used to declare invariants, base types, etc private members.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/config.hpp>
|
||||
#include <boost/contract/detail/decl.hpp>
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
@@ -40,14 +44,20 @@ namespace boost {
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
// NOTE: Not making this class friend will cause compiler errors on some
|
||||
// compilers (e.g., MSVC) because the private members needed for contracts
|
||||
// will not be accessible. On other compilers (e.g., GCC and CLang), the
|
||||
// private access will instead simply fail SFINAE and no compiler error will be
|
||||
// reported but invariants and subcontracting checking will be silently skipped
|
||||
// at run-time. Therefore programmers must make sure to either declare contract
|
||||
// members public or to make this class a friend.
|
||||
/**
|
||||
Friend class to declare invariants, base types, etc private members.
|
||||
Declare this class as friend of the class being contracted in order to declare
|
||||
the class invariants member functions and the base types as non-public members.
|
||||
@note Not making this class friend will cause compiler errors on some compilers
|
||||
(e.g., MSVC) because the private members needed for 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 but invariants and
|
||||
subcontracting will be silently be skipped at run-time. Therefore programmers
|
||||
must make sure to either declare contract members public or to make this class
|
||||
a friend.
|
||||
*/
|
||||
class access { // Copyable (as shell with no data member).
|
||||
/** @cond */
|
||||
// No public APIs (so users cannot use it directly by mistake).
|
||||
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
@@ -124,6 +134,7 @@ class access { // Copyable (as shell with no data member).
|
||||
|
||||
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
|
||||
OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs)
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Configuration macros.
|
||||
*/
|
||||
|
||||
// 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
|
||||
@@ -16,78 +18,229 @@
|
||||
|
||||
// TODO: Document that when contracts are programmed in .cpp and all these lib headers are #include only from within .cpp, then a given lib can be compiled for example without inv/post, only with pre. The code that will link to that lib will not be able to enable inv/post, or disable the pre. However, if contracts are programmed in .hpp and this lib headers are #included in .hpp that are shipped to users with a given lib, users of that lib can turn on/off all contracts for the shipped lib as well.
|
||||
|
||||
// BOOST_CONTRACT_DYN_LINK
|
||||
// BOOST_CONTRACT_HEADER_ONLY
|
||||
|
||||
// Rationale: Named after BOOST_DISABLE_THREADS, BOOST_ASIO_DISABLE_THREADS, etc.
|
||||
// BOOST_CONTRACT_DISABLE_THREADS
|
||||
|
||||
// Rationale: Named after BOOST_FUNCTION_MAX_ARGS, etc.
|
||||
#ifndef BOOST_CONTRACT_MAX_ARGS
|
||||
# define BOOST_CONTRACT_MAX_ARGS 10
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Define this macro to compile this library as a shared library or DLL
|
||||
(undefined by default).
|
||||
In general, this library must be compiled as a shared library defining this
|
||||
macro when used by multiple programs otherwise the contracts will not
|
||||
necessarily be checked correctly at run-time.
|
||||
<b>Rationale:</b> Named after @c BOOST_ALL_DYN_LINK.
|
||||
@see @RefSect{getting_started, Getting Started}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_DYN_LINK
|
||||
#endif
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Define this macro to compile user code with this library composed of headers
|
||||
only (undefined by default).
|
||||
If this macro is defined, this library does not have to be compiled
|
||||
separately. This library headers can simply be included in the user program
|
||||
and this library code will be compiled directly as part of the user program.
|
||||
However, in general this library must be compiled as a shared library
|
||||
defining @RefMacro{BOOST_CONTRACT_DYN_LINK} when used by multiple programs
|
||||
otherwise the contracts will not necessarily be checked correctly at
|
||||
run-time.
|
||||
<b>Rationale:</b> Named after @c BOOST_CHRONO_HEADER_ONLY.
|
||||
@see @RefSect{getting_started, Getting Started}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_HEADER_ONLY
|
||||
#endif
|
||||
|
||||
#ifdef 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
|
||||
strictly under single-threaded applications. However, when this macro is
|
||||
left undefined this library needs to use "global" locks to ensure contract
|
||||
checking is globally disabled when other contracts are being checked and
|
||||
also to safely access the failure handler functors (this could introduce a
|
||||
significant amount of synchronization in multi-threaded applications).
|
||||
<b>Rationale:</b> Named after @c BOOST_DISABLE_THREADS,
|
||||
@c BOOST_ASIO_DISABLE_THREADS, etc.
|
||||
@see @RefSect{contract_programming_overview, Contract Programming Overview}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_DISABLE_THREADS
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTRACT_MAX_ARGS
|
||||
/**
|
||||
Maximum number of function arguments when no variadic macros are supported
|
||||
(default to @c 10).
|
||||
This defines the maximum number of arguments of the overriding public
|
||||
function pointer passed to @RefFunc{boost::contract::public_function} on
|
||||
compilers that do not support variadic macros. This macro has no effect on
|
||||
compilers that support variadic macros.
|
||||
@note Regardless of the value of this macro and of compiler support for
|
||||
variadic macros, there is an intrinsic limit around 19 arguments
|
||||
for overriding public functions (because of a similar limit of some
|
||||
Boost libraries like Boost.MPL and Boost.FunctionTypes internally
|
||||
used by this library).
|
||||
|
||||
<b>Rationale:</b> Named after @c BOOST_FUNCTION_MAX_ARGS, etc.
|
||||
*/
|
||||
#define BOOST_CONTRACT_MAX_ARGS 10
|
||||
#endif
|
||||
|
||||
// Rationale: This cannot be called BASE_TYPES because BASE_TYPES(...) is already used as the macro to extract the public bases... so BASE_TYPEDEF seemed a reasonable naming alternative, but don't change base_types default #define because `typedef BASE_TYPES(...) base_types` is usually the best syntax in user's code.
|
||||
#ifndef BOOST_CONTRACT_BASE_TYPEDEF
|
||||
/**
|
||||
Define the name of the base type @c typedef (@c base_types by default).
|
||||
<b>Rationale:</b> This cannot be called @c BOOST_CONTRACT_BASE_TYPES
|
||||
because that is already used as the name of macro to
|
||||
extract the public bases. Then
|
||||
@c BOOST_CONTRACT_BASE_TYPEDEF is a reasonable naming
|
||||
alternative (but without changing this macro default to
|
||||
@c base_typedef because
|
||||
<c>typedef BOOST_CONTRACT_BASE_TYPES(...) base_types</c>
|
||||
is the preferred syntax in user code).
|
||||
*/
|
||||
#define BOOST_CONTRACT_BASE_TYPEDEF base_types
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTRACT_INVARIANT
|
||||
/**
|
||||
Define the name of the @c const and <c>const volatile</c> member functions
|
||||
that checks mutable and volatile class invariants respectively (@c invariant
|
||||
by default).
|
||||
*/
|
||||
#define BOOST_CONTRACT_INVARIANT invariant
|
||||
#endif
|
||||
|
||||
// C++ does not allow to overload member functions based on static classifier,
|
||||
// so a name different from the non-static class invariant member must be used.
|
||||
#ifndef BOOST_CONTRACT_STATIC_INVARIANT
|
||||
/**
|
||||
Define the name of the @c static member function that checks static class
|
||||
invariants (@c static_invariant by default).
|
||||
@note C++ does not allow to overload member functions based on static
|
||||
classifier, so a name different from the non-static class invariant
|
||||
name expanded by @RefMacro{BOOST_CONTRACT_INVARIANT} must be used
|
||||
here.
|
||||
*/
|
||||
#define BOOST_CONTRACT_STATIC_INVARIANT static_invariant
|
||||
#endif
|
||||
|
||||
// BOOST_CONTRACT_PERMISSIVE
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Disable a number of static checks and compiler warnings generated by this
|
||||
library (undefined by default).
|
||||
Among other things, this macro checks:
|
||||
@li Static invariant member function is @c static.
|
||||
@li Non-static invariant member function is either @c const,
|
||||
<c>const volatile</c>, or <c>volatile const</c>.
|
||||
@li A class that has contracts for one or more overriding public functions
|
||||
must also define the @RefMacro{BOOST_CONTRACT_BASE_TYPES} @c typedef.
|
||||
*/
|
||||
#define BOOST_CONTRACT_PERMISSIVE
|
||||
#endif
|
||||
|
||||
// Type of exception to throw is `guard c = ...` is missing. This is a
|
||||
// programming error so by default this library calls abort. If this macro is
|
||||
// #defined however, this library will throw the exception specified by the
|
||||
// macro value instead of calling abort. When #defined, this macro must be a
|
||||
// default constructible type.
|
||||
// Code instruction(s) to execute when contracts are missing `guard c = ...`.
|
||||
// In general, this is #undefined and this library calls `assert(false)` when
|
||||
// contract guards are missing. Missing a contract guard is a logic error in
|
||||
// the program (similar to dereferencing a null pointer) so terminating the
|
||||
// program via `abort` or `assert` as this library does by default is the only
|
||||
// safe thing to do. Therefore, it is recommended to never #define this macro.
|
||||
// However, this macro can be defined to throw an exception, call a function,
|
||||
// a no-op, or any other user code in case users truly need to handle missing
|
||||
// contract guard logic errors without terminating the program, for example:
|
||||
// #define BOOST_CONTRACT_ON_MISSING_GUARD { throw my_logic_error(); }
|
||||
// (It can even be defined to expand to nothing.)
|
||||
// BOOST_CONTRACT_ON_MISSING_GUARD
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Code block to execute if <c>boost::contract::guard c = ...</c> assignment is
|
||||
missing (undefined by default).
|
||||
In general, if programmer omit this assignment, it is a logic error in the
|
||||
program. Therefore, when this macro is not defined, by default this library
|
||||
calls calls @c assert with a @c false condition. If this macro is defined,
|
||||
this library will execute the code expanded by this macro instead of calling
|
||||
@c assert.
|
||||
*/
|
||||
#define OOST_CONTRACT_ON_MISSING_GUARD
|
||||
#endif
|
||||
|
||||
// Contract checking is not disable while checking preconditions.
|
||||
// This is what N1962 does by default. N1962 authors indicated it can be shown
|
||||
// that unchecked arguments are passed to function bodies if contract checking
|
||||
// is disable within precondition checking).
|
||||
// However, not disabling contract checking while checking preconditions can
|
||||
// lead to infinite recursive call in user code so by default this macro is
|
||||
// not defined.
|
||||
// TODO: Rename this BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTIONS
|
||||
// BOOST_CONTRACT_PRECONDITIONS_DISABLE_NOTHING
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
If defined, checking preconditions does not disable checking of other
|
||||
assertions (undefined by default).
|
||||
This is what [N1962] does by default because unchecked arguments are passed
|
||||
to function bodies if contract checking is disable within precondition
|
||||
checking (function bodies need to be executed directly or indirectly while
|
||||
checking the preconditions in question). However, not disabling assertion
|
||||
checking while checking preconditions can lead to infinite recursive calls
|
||||
in user code so by default this macro is not defined.
|
||||
*/
|
||||
#define OOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
|
||||
#endif
|
||||
|
||||
// BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
// BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
If defined, this library does not check preconditions at run-time (undefined
|
||||
by default).
|
||||
This library implementation code is also optimized to avoid overhead in
|
||||
associated with precondition checking when possible also at compile-time.
|
||||
Users can manually program @c #ifdef statements using this macro to disable
|
||||
precondition compilation (not just run-time checking).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
If defined, this library does not check postconditions at run-time
|
||||
(undefined by default).
|
||||
This library implementation code is also optimized to avoid overhead in
|
||||
associated with postcondition checking when possible also at compile-time.
|
||||
Users can manually program @c #ifdef statements using this macro to disable
|
||||
postcondition compilation (not just run-time checking).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
#endif
|
||||
|
||||
#if defined(DOXYGEN) || (!defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS))
|
||||
/**
|
||||
If defined, this library does not check entry invariants at run-time
|
||||
(undefined by default).
|
||||
This library implementation code is also optimized to avoid overhead in
|
||||
associated with entry invariant checking when possible also at compile-time.
|
||||
Users can manually program @c #ifdef statements using this macro to disable
|
||||
class invariant compilation (not just run-time checking).
|
||||
|
||||
This macro can always be defined by itself but it is also automatically
|
||||
defined when @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined.
|
||||
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_ENTRY_INVARIANTS
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
#if defined(DOXYGEN) || (!defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS))
|
||||
/**
|
||||
If defined, this library does not check exit invariant at run-time
|
||||
(undefined by default).
|
||||
This library implementation code is also optimized to avoid overhead in
|
||||
associated with exit invariant checking when possible also at compile-time.
|
||||
Users can manually program @c #ifdef statements using this macro to disable
|
||||
class invariant compilation (not just run-time checking).
|
||||
|
||||
This macro can always be defined by itself but it is also automatically
|
||||
defined when @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined.
|
||||
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#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 at run-time
|
||||
(undefined by default).
|
||||
This library implementation code is also optimized to avoid overhead in
|
||||
associated with class invariant checking when possible also at compile-time.
|
||||
Users can manually program @c #ifdef statements using this macro to disable
|
||||
class invariant compilation (not just run-time checking).
|
||||
|
||||
This macro can always be defined by itself but it is also automatically
|
||||
defined when @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS} and
|
||||
@RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS} are both defined.
|
||||
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_INVARIANTS
|
||||
#endif
|
||||
|
||||
@@ -98,6 +251,21 @@
|
||||
#error "define NO_ENTRY_INVARIANTS, NO_EXIT_INVARIANTS, and NO_POSTCONDITIONS instead"
|
||||
#elif defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
/**
|
||||
This library defines this macro if constructor contracts are not being
|
||||
checked by @RefFunc{boost::contract::constructor}.
|
||||
This macro is automatically defined or not by this library, and it is not a
|
||||
configuration macro. This library will generate a compile-time error if
|
||||
users manually define this macro.
|
||||
Users can manually define @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}, and
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead.
|
||||
|
||||
Note that constructor preconditions are checked separately by
|
||||
@RefClass{boost::contract::constructor_precondition} so their run-time check
|
||||
ing is disabled by @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} directly.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_CONSTRUCTORS
|
||||
#endif
|
||||
|
||||
@@ -105,6 +273,18 @@
|
||||
#error "define NO_ENTRY_INVARIANTS, NO_EXIT_INVARIANTS, and NO_POSTCONDITIONS instead"
|
||||
#elif defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
/**
|
||||
This library defines this macro if destructor contracts are not being
|
||||
checked by @RefFunc{boost::contract::destructor}.
|
||||
This macro is automatically defined or not by this library, and it is not a
|
||||
configuration macro. This library will generate a compile-time error if
|
||||
users manually define this macro.
|
||||
Users can manually define @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}, and
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead.
|
||||
(Note that destructors have no preconditions.)
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_DESTRUCTORS
|
||||
#endif
|
||||
|
||||
@@ -113,6 +293,18 @@
|
||||
#elif defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
/**
|
||||
This library defines this macro if public function contracts are not being
|
||||
checked by @RefFunc{boost::contract::public_function}.
|
||||
This macro is automatically defined or not by this library, and it is not a
|
||||
configuration macro. This library will generate a compile-time error if
|
||||
users manually define this macro.
|
||||
Users can manually define @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}, and
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
|
||||
#endif
|
||||
|
||||
@@ -120,6 +312,17 @@
|
||||
#error "define NO_PRECONDITIONS and NO_POSTCONDITIONS instead"
|
||||
#elif defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_POSTCONDITIONS)
|
||||
/**
|
||||
This library defines this macro if non-member, private, or protected
|
||||
function contracts are not being checked by
|
||||
@RefFunc{boost::contract::function}.
|
||||
This macro is automatically defined or not by this library, and it is not a
|
||||
configuration macro. This library will generate a compile-time error if
|
||||
users manually define this macro.
|
||||
Users can manually define @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} and
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_FUNCTIONS
|
||||
#endif
|
||||
|
||||
@@ -129,6 +332,18 @@
|
||||
defined(BOOST_CONTRACT_NO_DESTRUCTORS) && \
|
||||
defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) && \
|
||||
defined(BOOST_CONTRACT_NO_FUNCTIONS)
|
||||
/**
|
||||
This library defines this macro if no contracts (for any operation) are
|
||||
being checked.
|
||||
This macro is automatically defined or not by this library, and it is not a
|
||||
configuration macro. This library will generate a compile-time error if
|
||||
users manually define this macro.
|
||||
Users can manually define @RefMacro{BOOST_CONTRACT_NO_ENTRY_INVARIANTS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS},
|
||||
@RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}, and
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_NO_ALL
|
||||
#endif
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Exception and utilities to report contract assertion failures.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/declspec.hpp>
|
||||
#include <boost/function.hpp>
|
||||
@@ -23,43 +25,121 @@
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
// Placeholder base class to group all this lib exceptions.
|
||||
// IMPORTANT: Must not inherit from std::exception as derived exceptions will.
|
||||
/**
|
||||
Public base class for all this library exceptions.
|
||||
This class does not inherit from @c std::exception because derived exceptions
|
||||
will (inheriting from @c std::exception, or @c std::bad_cast, etc.).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
class BOOST_CONTRACT_DETAIL_DECLSPEC exception {
|
||||
public:
|
||||
virtual ~exception();
|
||||
/** Destruct this object. */
|
||||
virtual ~exception() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
};
|
||||
|
||||
// Rationale: boost::bad_any_cast exception does not print from/to type names,
|
||||
// so throw custom exception.
|
||||
/**
|
||||
Exception internally thrown by for inconsistent return values passed to
|
||||
overridden virtual public functions.
|
||||
This exception is internally thrown by this library when users specify a return
|
||||
value for an overriding public function in a derived class that is inconsistent
|
||||
with the return type of the virtual public function being overridden in the base
|
||||
class.
|
||||
|
||||
<b>Rationale:</b> The @c boost::bad_any_cast exception could not be used
|
||||
because it does not print the from and to type names (so it
|
||||
is not descriptive enough).
|
||||
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
*/
|
||||
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 types.
|
||||
@param from_type_name Name of the source type.
|
||||
@param to_type_name Name of the type destination type.
|
||||
*/
|
||||
explicit bad_virtual_result_cast(char const* from_type_name,
|
||||
char const* to_type_name);
|
||||
virtual ~bad_virtual_result_cast();
|
||||
|
||||
virtual char const* what() const BOOST_NOEXCEPT;
|
||||
/** Destruct this object. */
|
||||
virtual ~bad_virtual_result_cast() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/** Return an error description (containing both from and to type names). */
|
||||
virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/** @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).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
class BOOST_CONTRACT_DETAIL_DECLSPEC assertion_failure : // Copy (as str, etc.).
|
||||
public std::exception, public boost::contract::exception {
|
||||
public:
|
||||
/**
|
||||
Construct this object optionally with assertion file, line, and code
|
||||
information.
|
||||
This constructor can also be used to specify no information, or to specify
|
||||
only file and line but not code information (because of its 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 String text of the condition code being asserted.
|
||||
*/
|
||||
explicit assertion_failure(char const* const file = "",
|
||||
unsigned long const line = 0, char const* const code = "");
|
||||
|
||||
/**
|
||||
Construct this object with code information.
|
||||
This constructor can be used to specify only code but no file and line
|
||||
information.
|
||||
@param code String text of the condition code being asserted.
|
||||
*/
|
||||
explicit assertion_failure(char const* const code);
|
||||
virtual ~assertion_failure();
|
||||
|
||||
/** Destruct this object. */
|
||||
virtual ~assertion_failure() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
// Return something like `assertion "..." failed: file "...", line ...`.
|
||||
virtual char const* what() const BOOST_NOEXCEPT;
|
||||
/**
|
||||
Return string describing the failed assertion.
|
||||
@return Return a string similar to
|
||||
<c>assertion "`code()`" failed: file "`file()`", line \`line()\`</c>
|
||||
(parts of this information will be omitted if they were not
|
||||
specified at construction).
|
||||
*/
|
||||
virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/**
|
||||
Return assertion file.
|
||||
@return Return file as specified at construction (or @c "" if no file was
|
||||
specified).
|
||||
*/
|
||||
char const* const file() const;
|
||||
|
||||
/**
|
||||
Return assertion line number.
|
||||
@return Return line number as specified at construction (or @c 0 if no line
|
||||
number was specified).
|
||||
*/
|
||||
unsigned long line() const;
|
||||
|
||||
/**
|
||||
Return assertion condition code.
|
||||
@return Return assertion condition code as specified at construction (or
|
||||
@c "" if no code was specified at construction).
|
||||
*/
|
||||
char const* const code() const;
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -67,63 +147,157 @@ private:
|
||||
unsigned long const line_;
|
||||
char const* const code_;
|
||||
std::string what_;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
enum from { from_constructor, from_destructor, from_function };
|
||||
/**
|
||||
Context of assertion failure.
|
||||
This is passed as a parameter of the assertion failure handler functions.
|
||||
For example, it might be necessary to know the kind of operation that threw an
|
||||
assertion failure to make sure exception are never thrown by destructors even
|
||||
when contract failures are handled by throwing exceptions instead of terminating
|
||||
the program (default).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
enum from {
|
||||
/** Assertion failed in constructor contract. */
|
||||
from_constructor,
|
||||
/** Assertion failed in destructor contract. */
|
||||
from_destructor,
|
||||
/** Assertion failed in function (member or not) contract. */
|
||||
from_function
|
||||
};
|
||||
|
||||
// Use Boost.Function to handle also lambdas, binds, etc,
|
||||
/**
|
||||
Typef all assertion failure handler functions.
|
||||
<b>Rationale:</b> Using Boost.Function to handle also lambdas, binds, etc.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
typedef boost::function<void (from)> assertion_failure_handler;
|
||||
|
||||
assertion_failure_handler
|
||||
BOOST_CONTRACT_DETAIL_DECLSPEC set_precondition_failure(
|
||||
assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
assertion_failure_handler
|
||||
BOOST_CONTRACT_DETAIL_DECLSPEC get_precondition_failure()
|
||||
/**
|
||||
Set the precondition failure handler.
|
||||
@param f New precondition failure handler functor.
|
||||
@return Old precondition failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_precondition_failure(assertion_failure_handler const& f)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC precondition_failure(from where)
|
||||
/* can throw */;
|
||||
/**
|
||||
Return the precondition failure handler.
|
||||
@return Current precondition failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
get_precondition_failure() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
assertion_failure_handler
|
||||
BOOST_CONTRACT_DETAIL_DECLSPEC set_postcondition_failure(
|
||||
assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
/**
|
||||
Call the precondition hander functor.
|
||||
This is typically only called internally by this library.
|
||||
@param where Context of precondition failure.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
precondition_failure(from where) /* can throw */;
|
||||
|
||||
assertion_failure_handler
|
||||
BOOST_CONTRACT_DETAIL_DECLSPEC get_postcondition_failure()
|
||||
/**
|
||||
Set the postcondition failure handler.
|
||||
@param f New postcondition failure handler functor.
|
||||
@return Old postcondition failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_postcondition_failure(assertion_failure_handler const& f)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC postcondition_failure(from where)
|
||||
/* can throw */;
|
||||
/**
|
||||
Return the postcondition failure handler.
|
||||
@return Current postcondition failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
get_postcondition_failure() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/**
|
||||
Call the postcondition hander functor.
|
||||
This is typically only called internally by this library.
|
||||
@param where Context of postcondition failure.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
postcondition_failure(from where) /* can throw */;
|
||||
|
||||
/**
|
||||
Set the entry invariant failure handler.
|
||||
@param f New entry invariant failure handler functor.
|
||||
@return Old entry invariant failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_entry_invariant_failure(assertion_failure_handler const& f)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/**
|
||||
Return the entry invariant failure handler.
|
||||
@return Current entry invariant failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
get_entry_invariant_failure() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC entry_invariant_failure(from where)
|
||||
/* can throw */;
|
||||
/**
|
||||
Call the entry invariant hander functor.
|
||||
This is typically only called internally by this library.
|
||||
@param where Context of entry invariant failure.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
entry_invariant_failure(from where) /* can throw */;
|
||||
|
||||
/**
|
||||
Set the exit invariant failure handler.
|
||||
@param f New exit invariant failure handler functor.
|
||||
@return Old exit invariant failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_exit_invariant_failure(assertion_failure_handler const& f)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
/**
|
||||
Return the exit invariant failure handler.
|
||||
@return Current exit invariant failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
assertion_failure_handler
|
||||
BOOST_CONTRACT_DETAIL_DECLSPEC get_exit_invariant_failure()
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC exit_invariant_failure(from where)
|
||||
/* can throw */;
|
||||
/**
|
||||
Call the exit invariant hander functor.
|
||||
This is typically only called internally by this library.
|
||||
@param where Context of exit invariant failure.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
exit_invariant_failure(from where) /* can throw */;
|
||||
|
||||
// Set all inv failures (entry inv and exit inv) at once.
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC set_invariant_failure(
|
||||
assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
/**
|
||||
Set the both entry and exit invariant failure handlers at once (for
|
||||
convenience).
|
||||
@param f New invariant failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_invariant_failure(assertion_failure_handler const& f)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
// Set all failures (pre, post, entry inv, and exit int) at once.
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC set_failure(
|
||||
assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
/**
|
||||
Set the all (precondition, postcondition, entry and exit invariant) failure
|
||||
handlers at once (for convenience).
|
||||
@param f New failure handler functor.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
void BOOST_CONTRACT_DETAIL_DECLSPEC
|
||||
set_failure(assertion_failure_handler const& f) BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
} } // namespace
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Used to prevent setting other contract conditions after postconditions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/config.hpp>
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
@@ -33,12 +35,19 @@ namespace boost {
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
Used to prevent setting other contract conditions after postconditions.
|
||||
This class has no member function so it cannot be used to set any contract
|
||||
functor.
|
||||
*/
|
||||
class set_nothing { // Copyable (as *).
|
||||
public:
|
||||
/** Destruct this object. */
|
||||
~set_nothing() BOOST_NOEXCEPT_IF(false) {}
|
||||
|
||||
// No set member functions here.
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
@@ -62,6 +71,7 @@ private:
|
||||
|
||||
template<typename RR>
|
||||
friend class set_postcondition_only;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Allow to specify old value assignments and postconditions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/set_postcondition_only.hpp>
|
||||
#include <boost/contract/core/set_nothing.hpp>
|
||||
@@ -32,12 +34,34 @@ namespace boost {
|
||||
}
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
|
||||
/**
|
||||
Allow to specify old value assignments and postconditions.
|
||||
Allow to program functors this library will call to assign old values before
|
||||
body execution and to check postconditions.
|
||||
@tparam R Return type of the function being contracted if that function is a
|
||||
non-void virtual or overriding public function, otherwise this is
|
||||
always @c void.
|
||||
@see @RefSect{tutorial, Tutorial}, @RefSect{advanced_topics, Advances Topics}.
|
||||
*/
|
||||
template<typename R = void>
|
||||
class set_old_postcondition { // Copyable (as *).
|
||||
public:
|
||||
/** Destruct this object. */
|
||||
~set_old_postcondition() BOOST_NOEXCEPT_IF(false) {}
|
||||
|
||||
/**
|
||||
Allow to specify old value assignments to execute just before function body.
|
||||
@param f Functor called by this library to assign old values. This
|
||||
functor is called just before the function body is executed, but
|
||||
after preconditions and class invariants are checked. Old values
|
||||
are usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. This
|
||||
functor must be a nullary functor. This functor should capture
|
||||
old value pointers (and in general all other variables) by
|
||||
(constant) reference.
|
||||
@return After old value assignments have been specified, return object that
|
||||
allows to optionally specify postconditions.
|
||||
*/
|
||||
template<typename F>
|
||||
set_postcondition_only<R> old(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -53,6 +77,21 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Allow to specify postconditions.
|
||||
@param f Functor called by this library to check postconditions. Any
|
||||
exception thrown by a call to this functor indicates a
|
||||
postcondition failure. Assertions within this functor are
|
||||
usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}. This
|
||||
functor must be a nullary functor if @c R is @c void, otherwise
|
||||
it must be unary functor taking the return value as a parameter
|
||||
of type <c>R const&</c> (to avoid extra copies, or @c R and also
|
||||
<c>R const</c> if extra copies of the return value are
|
||||
irrelevant). This functor should capture variables by
|
||||
(constant) reference.
|
||||
@return After postconditions have been specified, return object that does
|
||||
not allow to specify any additional contract (i.e., set nothing).
|
||||
*/
|
||||
template<typename F>
|
||||
set_nothing postcondition(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -68,6 +107,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
@@ -91,6 +131,7 @@ private:
|
||||
|
||||
template<class CC>
|
||||
friend set_old_postcondition<> destructor(CC* oobj);
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Allow to specify postconditions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/set_nothing.hpp>
|
||||
#include <boost/contract/core/config.hpp>
|
||||
@@ -34,12 +36,36 @@ namespace boost {
|
||||
}
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
|
||||
/**
|
||||
Allow to specify postconditions.
|
||||
Allow to program functors this library will call to check postconditions.
|
||||
@tparam R Return type of the function being contracted if that function is a
|
||||
non-void virtual or overriding public function, otherwise this is
|
||||
always @c void.
|
||||
@see @RefSect{tutorial, Tutorial}, @RefSect{advanced_topics, Advances Topics}.
|
||||
*/
|
||||
template<typename R = void>
|
||||
class set_postcondition_only { // Copyable (as *).
|
||||
public:
|
||||
/** Destruct this object. */
|
||||
~set_postcondition_only() BOOST_NOEXCEPT_IF(false) {}
|
||||
|
||||
/**
|
||||
Allow to specify postconditions.
|
||||
@param f Functor called by this library to check postconditions. Any
|
||||
exception thrown by a call to this functor indicates a
|
||||
postcondition failure. Assertions within this functor are
|
||||
usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}. This
|
||||
functor must be a nullary functor if @c R is @c void, otherwise
|
||||
it must be unary functor taking the return value as a parameter
|
||||
of type <c>R const&</c> (to avoid extra copies, or @c R and also
|
||||
<c>R const</c> if extra copies of the return value are
|
||||
irrelevant). This functor should capture variables by
|
||||
(constant) reference.
|
||||
@return After postconditions have been specified, return object that does
|
||||
not allow to specify any additional contract (i.e., set nothing).
|
||||
*/
|
||||
template<typename F>
|
||||
set_nothing postcondition(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -55,6 +81,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
@@ -74,6 +101,7 @@ private:
|
||||
friend class set_precondition_old_postcondition<R>;
|
||||
|
||||
friend class set_old_postcondition<R>;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Allow to specify preconditions, old value assignments, and postconditions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/set_old_postcondition.hpp>
|
||||
#include <boost/contract/core/set_postcondition_only.hpp>
|
||||
@@ -34,12 +36,39 @@ namespace boost {
|
||||
}
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
template<typename R /* = void (already in fwd decl from decl.hpp) */>
|
||||
|
||||
/**
|
||||
Allow to specify preconditions, old value assignments, and postconditions.
|
||||
Allow to program functors this library will call to check preconditions, assign
|
||||
old values before body execution, and check postconditions.
|
||||
@tparam R Return type of the function being contracted if that function is a
|
||||
non-void virtual or overriding public function, otherwise this is
|
||||
always @c void.
|
||||
@see @RefSect{tutorial, Tutorial}, @RefSect{advanced_topics, Advances Topics}.
|
||||
*/
|
||||
template<
|
||||
typename R /* = void (already in fwd decl from decl.hpp) */
|
||||
#ifdef DOXYGEN
|
||||
= void
|
||||
#endif
|
||||
>
|
||||
class set_precondition_old_postcondition { // Copyable (as *).
|
||||
public:
|
||||
/** Destruct this object. */
|
||||
~set_precondition_old_postcondition() BOOST_NOEXCEPT_IF(false) {}
|
||||
|
||||
/**
|
||||
Allow to specify preconditions.
|
||||
@param f Functor called by this library to check preconditions. Any
|
||||
exception thrown by a call to this functor indicates a
|
||||
precondition failure. Assertions within this functor are usually
|
||||
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}. This functor
|
||||
must be a nullary functor. This functor could capture variables
|
||||
by value, or better by (constant) reference to avoid extra
|
||||
copies.
|
||||
@return After preconditions have been specified, return object that allows
|
||||
to optionally specify old value assignments and postconditions.
|
||||
*/
|
||||
template<typename F>
|
||||
set_old_postcondition<R> precondition(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
@@ -55,6 +84,18 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Allow to specify old value assignments to execute just before function body.
|
||||
@param f Functor called by this library to assign old values. This
|
||||
functor is called just before the function body is executed, but
|
||||
after preconditions and class invariants are checked. Old values
|
||||
are usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. This
|
||||
functor must be a nullary functor. This functor should capture
|
||||
old value pointers (and in general all other variables) by
|
||||
(constant) reference.
|
||||
@return After old value assignments have been specified, return object that
|
||||
allows to optionally specify postconditions.
|
||||
*/
|
||||
template<typename F>
|
||||
set_postcondition_only<R> old(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -70,6 +111,21 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Allow to specify postconditions.
|
||||
@param f Functor called by this library to check postconditions. Any
|
||||
exception thrown by a call to this functor indicates a
|
||||
postcondition failure. Assertions within this functor are
|
||||
usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}. This
|
||||
functor must be a nullary functor if @c R is @c void, otherwise
|
||||
it must be unary functor taking the return value as a parameter
|
||||
of type <c>R const&</c> (to avoid extra copies, or @c R and also
|
||||
<c>R const</c> if extra copies of the return value are
|
||||
irrelevant). This functor should capture variables by
|
||||
(constant) reference.
|
||||
@return After postconditions have been specified, return object that does
|
||||
not allow to specify any additional contract (i.e., set nothing).
|
||||
*/
|
||||
template<typename F>
|
||||
set_nothing postcondition(F const& f) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -85,6 +141,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
@@ -120,6 +177,7 @@ private:
|
||||
|
||||
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
|
||||
OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs)
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
// 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
|
||||
Used to contract virtual public functions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/core/config.hpp>
|
||||
#include <boost/contract/detail/decl.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
@@ -28,7 +32,20 @@ namespace boost {
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
Class to mark virtual public functions.
|
||||
Virtual and overriding public functions contracted using this library must have
|
||||
an extra parameter at the very end of their parameter list. This parameter must
|
||||
be a pointer to this class and it must be assigned to @c 0 by default. (This
|
||||
extra parameter is often named @c v in this documentation, but any name can be
|
||||
used.)
|
||||
|
||||
<b>Rationale:</b> This extra parameter is internally used by this library to
|
||||
recognize virtual public functions and implement subcontracting.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
*/
|
||||
class virtual_ : private boost::noncopyable { // Avoid copy queue, stack, etc.
|
||||
/** @cond */
|
||||
// No public API (so users cannot use it directly by mistake).
|
||||
|
||||
enum action_enum {
|
||||
@@ -97,6 +114,7 @@ class virtual_ : private boost::noncopyable { // Avoid copy queue, stack, etc.
|
||||
|
||||
BOOST_CONTRACT_DETAIL_DECL_DETAIL_CHECK_SUBCONTRACTED_PRE_POST_INV_Z(1,
|
||||
/* is_friend = */ 1, OO, RR, FF, CC, AArgs);
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Program contracts for destructors.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
|
||||
@@ -17,6 +19,17 @@
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
Program contracts for destructors.
|
||||
Used to specify postconditions and check class invariants for destructors
|
||||
(destructors do not have preconditions).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param obj The destructor's object @c this.
|
||||
@return The result of this function must be assigned to a local variable of type
|
||||
@RefClass{boost::contract::guard} declared at the beginning of the
|
||||
destructor definition (after specifying old value assignments and
|
||||
postconditions if they are present).
|
||||
*/
|
||||
template<class C>
|
||||
set_old_postcondition<> destructor(C* obj) {
|
||||
// Must #if also on ..._PRECONDITIONS here because set_... is generic.
|
||||
|
||||
@@ -35,7 +35,7 @@ private:
|
||||
if(check_guard::checking()) return;
|
||||
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
{
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NOTHING
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
|
||||
check_guard checking;
|
||||
#endif
|
||||
this->check_pre();
|
||||
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
this->check_subcontracted_entry_inv();
|
||||
#endif
|
||||
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NOTHING
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
|
||||
this->check_subcontracted_pre();
|
||||
} // Release check guard.
|
||||
#else
|
||||
|
||||
@@ -50,7 +50,7 @@ private:
|
||||
this->check_entry_static_inv();
|
||||
#endif
|
||||
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NOTHING
|
||||
#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
|
||||
this->check_pre();
|
||||
} // Release check guard.
|
||||
#else
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Program contracts for non-member, private, and protected functions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
|
||||
@@ -17,6 +19,35 @@
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
Program contracts for non-member, private and protected functions.
|
||||
|
||||
Allow to program preconditions and postconditions (both optional) for
|
||||
non-member, private and protected functions (these functions never check
|
||||
invariants or participate in subcontracting).
|
||||
The result of this function must be assigned to a local variable of type
|
||||
@RefClass{boost::contract::guard} at the scope of the function being contracted.
|
||||
|
||||
@code
|
||||
// Enclosing function scope.
|
||||
boost::contract::guard c = boost::contract::function()
|
||||
.precondition(...) // Optional.
|
||||
.old(...) // Optional.
|
||||
.postcondition(...) // Optional.
|
||||
;
|
||||
... // Enclosing function body.
|
||||
@endcode
|
||||
|
||||
For optimization purposes this can be avoided for functions that do not have
|
||||
preconditions and postconditions.
|
||||
|
||||
Where <c>.precondition(...)</c>, <c>.old(...)</c>, and
|
||||
<c>.postcondition(...)</c> take nullary functors that assert preconditions,
|
||||
assign old value pointers just before body execution (most of the times it
|
||||
should be sufficient to assign these pointers where they are first declared
|
||||
instead), and assert postconditions respectively.
|
||||
@SeeAlso @RefSect{tutorial, Tutorial}
|
||||
*/
|
||||
set_precondition_old_postcondition<> function() {
|
||||
// Must #if also on ..._INVARIANTS here because set_... is generic.
|
||||
#if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
RAII object that checks the contracts.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#include <boost/contract/detail/condition/check_base.hpp>
|
||||
@@ -17,6 +19,8 @@
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
/** @cond */
|
||||
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_INVARIANTS)
|
||||
@@ -30,19 +34,30 @@
|
||||
#define BOOST_CONTRACT_GUARD_CTOR_DEF_(contract_type) {}
|
||||
#endif
|
||||
|
||||
// Following implicit to allow syntax `guard c = ...`.
|
||||
#define BOOST_CONTRACT_GUARD_CTOR_(contract_type) \
|
||||
/* implicit */ guard(contract_type const& contract) \
|
||||
BOOST_CONTRACT_GUARD_CTOR_DEF_(contract_type)
|
||||
/** @endcond */
|
||||
|
||||
/* CODE */
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
/**
|
||||
RAII object that checks the contracts.
|
||||
In general, this object checks entry invariants, preconditions, and assigns old
|
||||
values when it is constructed. It then checks exit invariants and postconditions
|
||||
when it is destructed. However, special attention in placed in marking sure
|
||||
postconditions are checked only if the body did not throw an exception,
|
||||
constructors never check entry invariants, destructor check exit invariants only
|
||||
if their body throws, etc. (see also
|
||||
@RefSect{contract_programming_overview, Contract Programming Overview}).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
*/
|
||||
class guard { // Non-copyable (but copy ctor ~= move via ptr release).
|
||||
public:
|
||||
// Following copy and implicit type conversion ctors allow `guard c = ...`.
|
||||
|
||||
/**
|
||||
Construct this object copying it from specified one.
|
||||
This object will check the contract, the copied-from object will not (i.e.,
|
||||
contract checking ownership is transfered to the this object).
|
||||
*/
|
||||
guard(guard const& other) // Copy ctor moves check_ pointer to dest.
|
||||
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
|
||||
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
|
||||
@@ -51,19 +66,106 @@ public:
|
||||
#endif
|
||||
{}
|
||||
|
||||
template<typename R>
|
||||
BOOST_CONTRACT_GUARD_CTOR_(set_precondition_old_postcondition<R>)
|
||||
|
||||
template<typename R>
|
||||
BOOST_CONTRACT_GUARD_CTOR_(set_old_postcondition<R>)
|
||||
|
||||
template<typename R>
|
||||
BOOST_CONTRACT_GUARD_CTOR_(set_postcondition_only<R>)
|
||||
|
||||
BOOST_CONTRACT_GUARD_CTOR_(set_nothing)
|
||||
/**
|
||||
Construct this object from specified contract.
|
||||
Check entry invariants (as they apply for specified contract).
|
||||
Implicit so initialization operator @c = can be used.
|
||||
|
||||
<b>Throws:</b> This can throw any exception (exception specification
|
||||
<c>noexcept(false)</c>) to allow to configure this library
|
||||
to throw on contract failure.
|
||||
@param contract Contract to be guarded by this object.
|
||||
@tparam R Return type of operation being contracted if that operation is a
|
||||
non-void virtual or overriding public function, otherwise this
|
||||
is always void.
|
||||
*/
|
||||
template<typename R>
|
||||
/* implicit */ guard(set_precondition_old_postcondition<R> const& contract)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_precondition_old_postcondition<R>)
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Construct this object from specified contract.
|
||||
Check entry invariants (as they apply for specified contract) and check
|
||||
preconditions.
|
||||
Implicit so initialization operator @c = can be used.
|
||||
|
||||
<b>Throws:</b> This can throw any exception (exception specification
|
||||
<c>noexcept(false)</c>) to allow to configure this library
|
||||
to throw on contract failure.
|
||||
@param contract Contract to be guarded by this object.
|
||||
@tparam R Return type of operation being contracted if that operation is a
|
||||
non-void virtual or overriding public function, otherwise this
|
||||
is always void.
|
||||
*/
|
||||
template<typename R>
|
||||
/* implicit */ guard(set_old_postcondition<R> const& contract)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_old_postcondition<R>)
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Construct this object from specified contract.
|
||||
Check entry invariants (as they apply for specified contract), check
|
||||
preconditions, and assign old values.
|
||||
Implicit so initialization operator @c = can be used.
|
||||
|
||||
<b>Throws:</b> This can throw any exception (exception specification
|
||||
<c>noexcept(false)</c>) to allow to configure this library
|
||||
to throw on contract failure.
|
||||
@param contract Contract to be guarded by this object.
|
||||
@tparam R Return type of operation being contracted if that operation is a
|
||||
non-void virtual or overriding public function, otherwise this
|
||||
is always void.
|
||||
*/
|
||||
template<typename R>
|
||||
/* implicit */ guard(set_postcondition_only<R> const& contract)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_postcondition_only<R>)
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Construct this object from specified contract.
|
||||
Check entry invariants (as they apply for specified contract), check
|
||||
preconditions, and assign old values. (In this case, the destructor of this
|
||||
object will also check postconditions.)
|
||||
Implicit so initialization operator @c = can be used.
|
||||
|
||||
<b>Throws:</b> This can throw any exception (exception specification
|
||||
<c>noexcept(false)</c>) to allow to configure this library
|
||||
to throw on contract failure.
|
||||
@param contract Contract to be guarded by this object.
|
||||
@tparam R Return type of operation being contracted if that operation is a
|
||||
non-void virtual or overriding public function, otherwise this
|
||||
is always void.
|
||||
*/
|
||||
/* implicit */ guard(set_nothing const& contract)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_nothing)
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Destroy this object.
|
||||
Check exit invariants (as they apply for specified contract). Check
|
||||
postconditions (if the body did not throw and postconditions where
|
||||
specified for the contract specified when constructing this object).
|
||||
|
||||
<b>Throws:</b> This can throw any exception (exception specification
|
||||
<c>noexcept(false)</c>) to allow to configure this library
|
||||
to throw on contract failure.
|
||||
*/
|
||||
~guard() BOOST_NOEXCEPT_IF(false) {} // Allow auto_ptr dtor to throw.
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
guard& operator=(guard const&); // Cannot copy outside of `guard c = ...`.
|
||||
|
||||
@@ -73,6 +175,7 @@ private:
|
||||
boost::contract::detail::auto_ptr<boost::contract::detail::check_base>
|
||||
check_;
|
||||
#endif
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// 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 */
|
||||
/** @file
|
||||
Facilities for old values.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#include <boost/contract/detail/check_guard.hpp>
|
||||
@@ -35,6 +37,8 @@ BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_pro
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
/** @cond */
|
||||
|
||||
#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
|
||||
#define BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value) /* nothing */
|
||||
#else
|
||||
@@ -55,10 +59,29 @@ BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_pro
|
||||
BOOST_CONTRACT_OLDOF_AUTO_TYPEOF_(value)(boost::contract::make_old( \
|
||||
boost::contract::copy_old() ? (value) : boost::contract::null_old() \
|
||||
))
|
||||
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
// NOTE: Leave this #defined the same regardless of ..._POSTCONDITIONS.
|
||||
/**
|
||||
Macro typically used to copy old value expressions.
|
||||
This is a variadic macro, program the old value expression copy manually on
|
||||
compilers that do not support variadic macros (see
|
||||
also @RefSect{advanced_topics, Advanced Topics}).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param ... This macro usually takes a single parameter as the expressions to
|
||||
be assigned to the old value. However, in virtual or overriding
|
||||
public functions where the extra
|
||||
@RefClass{boost::contract::virtual_}<c>*</c> function parameter must
|
||||
be used, this macro takes two parameters: The first parameter is
|
||||
the pointer to @RefClass{boost::contract::virtual_} and then the
|
||||
old value expression to be copied.
|
||||
@return The expression expanded by this macro should be assigned to an old
|
||||
value pointer, either @RefClass{boost::contract::old_ptr} or
|
||||
@RefClass{boost::contract::old_ptr_noncopyable}.
|
||||
*/
|
||||
#define BOOST_CONTRACT_OLDOF(...) \
|
||||
BOOST_PP_CAT( /* CAT(..., EMTPY()) required on MSVC */ \
|
||||
BOOST_PP_OVERLOAD( \
|
||||
@@ -72,30 +95,47 @@ BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_pro
|
||||
|
||||
/* CODE */
|
||||
|
||||
// Specialization because `unconvertible_old` incomplete type when trait used.
|
||||
/** @cond */
|
||||
namespace boost {
|
||||
namespace contract {
|
||||
class unconvertible_old;
|
||||
}
|
||||
|
||||
// Needed because `unconvertible_old` incomplete type when trait used.
|
||||
template<>
|
||||
struct is_copy_constructible<contract::unconvertible_old> : true_type {};
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
namespace boost { namespace contract {
|
||||
|
||||
template<typename T>
|
||||
class old_ptr_noncopyable;
|
||||
|
||||
/**
|
||||
Old value pointer (requires pointed old value type to be copyable).
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@tparam T Type of pointed old value. If this type is not copyable, this
|
||||
pointer will always be left null and this library will generate a
|
||||
compile-time error when this pointer is dereferenced of accessed.
|
||||
*/
|
||||
template<typename T>
|
||||
class old_ptr { /* copyable (as *) */
|
||||
public:
|
||||
/** Pointed old value type. */
|
||||
typedef T element_type;
|
||||
|
||||
/** Construct this object as a null old value pointer. */
|
||||
old_ptr() {}
|
||||
|
||||
/* only const access (contracts should not change old values) */
|
||||
|
||||
/**
|
||||
Dereference this old value pointer.
|
||||
This will generate a run-time error if this pointer is null and a
|
||||
compile-time error if the pointed type is not copyable.
|
||||
@return The old value (contract assertions should not change the state of
|
||||
the program so the old value is always returned as a constant
|
||||
reference and this member function is @c const).
|
||||
*/
|
||||
T const& operator*() const {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
boost::is_copy_constructible<T>::value,
|
||||
@@ -105,6 +145,13 @@ public:
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
/**
|
||||
Access the pointed old value.
|
||||
This will generate a compile-time error if the pointed type is not copyable.
|
||||
@return The old value (contract assertions should not change the state of
|
||||
the program so the old value is always returned as a pointer to
|
||||
constant object and this member function is @c const).
|
||||
*/
|
||||
T const* operator->() const {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
boost::is_copy_constructible<T>::value,
|
||||
@@ -113,8 +160,17 @@ public:
|
||||
return ptr_.operator->();
|
||||
}
|
||||
|
||||
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr<T>, !!ptr_)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr<T>, !!ptr_)
|
||||
#else
|
||||
/**
|
||||
Safe-bool operator.
|
||||
@return True if this pointer is not null, false otherwise.
|
||||
*/
|
||||
explicit operator bool() const;
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
explicit old_ptr(boost::shared_ptr<T const> ptr) :
|
||||
@@ -125,33 +181,72 @@ private:
|
||||
|
||||
friend class convertible_old;
|
||||
friend class old_ptr_noncopyable<T>;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
// Similar to above, but does not statically assert copy constructible.
|
||||
/**
|
||||
Old value pointer (does not require pointed old value type to be copyable).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
@tparam T Type of pointed old value. If this type is not copyable, this
|
||||
pointer will always be left null (but this library will not generate
|
||||
compile-time errors when this pointer is dereferenced of accessed).
|
||||
*/
|
||||
template<typename T>
|
||||
class old_ptr_noncopyable { /* copyable (as *) */
|
||||
public:
|
||||
/** Pointed old value type. */
|
||||
typedef T element_type;
|
||||
|
||||
/** Construct this object as a null old value pointer. */
|
||||
old_ptr_noncopyable() {}
|
||||
|
||||
// Required to assign to OLDOF (as OLDOF returns old_ptr for auto decl).
|
||||
/**
|
||||
Construct this object from a old value pointer for copyable-only types.
|
||||
Implicitly called when assign an object of this type to
|
||||
@RefMacro{BOOST_CONTRACT_OLDOF}.
|
||||
@param other Copyable-only old value pointer.
|
||||
*/
|
||||
/* implicit */ old_ptr_noncopyable(old_ptr<T> const& other) :
|
||||
ptr_(other.ptr_) {}
|
||||
|
||||
/* only const access (contracts should not change old values) */
|
||||
// Only const access (contracts should not change old values).
|
||||
|
||||
/**
|
||||
Dereference this old value pointer.
|
||||
This will generate a run-time error if this pointer is null (but no
|
||||
compile-time error if the pointed type is not copyable).
|
||||
@return The old value (contract assertions should not change the state of
|
||||
the program so the old value is always returned as a constant
|
||||
reference and this member function is @c const).
|
||||
*/
|
||||
T const& operator*() const {
|
||||
BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
/**
|
||||
Access the pointed old value.
|
||||
(This will not generate a compile-time error if the pointed type is not
|
||||
copyable.)
|
||||
@return The old value (contract assertions should not change the state of
|
||||
the program so the old value is always returned as a pointer to
|
||||
constant object and this member function is @c const).
|
||||
*/
|
||||
T const* operator->() const {
|
||||
return ptr_.operator->();
|
||||
}
|
||||
|
||||
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_noncopyable<T>, !!ptr_)
|
||||
#ifndef DOXYGEN
|
||||
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_noncopyable<T>, !!ptr_)
|
||||
#else
|
||||
/**
|
||||
Safe-bool operator.
|
||||
@return True if this pointer is not null, false otherwise.
|
||||
*/
|
||||
explicit operator bool() const;
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
explicit old_ptr_noncopyable(boost::shared_ptr<T const> ptr) :
|
||||
@@ -161,12 +256,26 @@ private:
|
||||
boost::shared_ptr<T const> ptr_;
|
||||
|
||||
friend class convertible_old;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
/**
|
||||
Internally hold old value copies.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
class unconvertible_old { // Copyable (as *).
|
||||
public:
|
||||
// Following implicitly called by ternary operator `... ? ... : null_old()`.
|
||||
|
||||
/**
|
||||
Construct this object from the specified old value (for copyable old value
|
||||
types).
|
||||
The specified old value is copied one time and the related old value pointer
|
||||
will not be null (as long as postconditions are being checked, see
|
||||
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}).
|
||||
@tparam T Old value type.
|
||||
@param old_value Old value to be copied.
|
||||
*/
|
||||
template<typename T>
|
||||
/* implicit */ unconvertible_old(
|
||||
T const& old_value,
|
||||
@@ -174,15 +283,24 @@ public:
|
||||
)
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
: ptr_(boost::make_shared<T>(old_value)) // The one single T's copy.
|
||||
#endif // Else, null ptr_ (so not copy of T).
|
||||
#endif // Else, leave ptr_ null (and no copy of T).
|
||||
{}
|
||||
|
||||
/**
|
||||
Construct this object from the specified old value (for non-copyable old
|
||||
value types).
|
||||
The specified old value cannot and so it is not copied in this case, thus
|
||||
the related old value pointer will always be null.
|
||||
@tparam T Old value type.
|
||||
@param old_value Old value (that will not be copied in this case).
|
||||
*/
|
||||
template<typename T>
|
||||
/* implicit */ unconvertible_old(
|
||||
T const&,
|
||||
T const& old_value,
|
||||
typename boost::disable_if<boost::is_copy_constructible<T> >::type* = 0
|
||||
) {} // Null ptr_ (so no copy of T).
|
||||
) {} // Leave ptr_ null (and no copy of T).
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
explicit unconvertible_old() {}
|
||||
|
||||
@@ -193,22 +311,38 @@ private:
|
||||
friend class convertible_old;
|
||||
|
||||
friend unconvertible_old null_old();
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
/**
|
||||
Internally convert old value copies to old value pointers.
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
class convertible_old { // Copyable (as *).
|
||||
public:
|
||||
// Implicitly called by ctor init `old_ptr_noncopyable<T> old_x = ...`.
|
||||
/**
|
||||
Convert this object to an old value pointer.
|
||||
For example, implicitly called when assigning or initializing an old value
|
||||
pointer.
|
||||
@tparam T Type of pointed old value (might or might be copyable).
|
||||
*/
|
||||
template<typename T>
|
||||
/* implicit */ operator old_ptr_noncopyable<T>() {
|
||||
return ptr<old_ptr_noncopyable<T> >();
|
||||
}
|
||||
|
||||
// Implicitly called by ctor init `old_ptr<T> old_x = ...`.
|
||||
/**
|
||||
Convert this object to an old value pointer.
|
||||
For example, implicitly called when assigning or initializing an old value
|
||||
pointer.
|
||||
@tparam T Type of pointed old value (must be copyable).
|
||||
*/
|
||||
template<typename T>
|
||||
/* implicit */ operator old_ptr<T>() {
|
||||
return ptr<old_ptr<T> >();
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
private:
|
||||
explicit convertible_old(virtual_* v, unconvertible_old const& old)
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
@@ -277,18 +411,43 @@ private:
|
||||
friend convertible_old make_old(unconvertible_old const&);
|
||||
|
||||
friend convertible_old make_old(virtual_*, unconvertible_old const&);
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Make a null old value copy (i.e., the related old value pointer will be null).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
unconvertible_old null_old() { return unconvertible_old(); }
|
||||
|
||||
/**
|
||||
Make an old value copy (for non virtual and not overriding public functions).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
@param old Old value (implicitly and automatically wrapped in
|
||||
@RefClass{boost::contract::uncovertible_old}).
|
||||
*/
|
||||
convertible_old make_old(unconvertible_old const& old) {
|
||||
return convertible_old(0, old);
|
||||
}
|
||||
|
||||
/**
|
||||
Make an old value copy (for virtual and overriding public functions).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
@param v Contracted virtual and overriding public function extra parameter.
|
||||
@param old Old value (implicitly and automatically wrapped in
|
||||
@RefClass{boost::contract::uncovertible_old}).
|
||||
*/
|
||||
convertible_old make_old(virtual_* v, unconvertible_old const& old) {
|
||||
return convertible_old(v, old);
|
||||
}
|
||||
|
||||
/**
|
||||
Return true if and only if old values need to be copied (for non virtual and
|
||||
not overriding public functions).
|
||||
For example, this function always returns false when postconditions are not
|
||||
being checked (see @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
*/
|
||||
bool copy_old() {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
return !boost::contract::detail::check_guard::checking();
|
||||
@@ -297,6 +456,14 @@ bool copy_old() {
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Return true if and only if old values need to be copied (for virtual and
|
||||
overriding public functions).
|
||||
For example, this function always returns false when postconditions are not
|
||||
being checked (see @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}).
|
||||
@see @RefSect{advanced_topics, Advanced Topics}.
|
||||
@param v Contracted virtual and overriding public function extra parameter.
|
||||
*/
|
||||
bool copy_old(virtual_* v) {
|
||||
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
|
||||
if(!v) return !boost::contract::detail::check_guard::checking();
|
||||
|
||||
@@ -7,18 +7,24 @@
|
||||
// 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
|
||||
Support contracts for overriding public functions.
|
||||
*/
|
||||
|
||||
#include <boost/contract/detail/all_core_headers.hpp>
|
||||
#include <boost/contract/detail/tvariadic.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
|
||||
#include <boost/contract/detail/type_traits/introspection.hpp>
|
||||
#include <boost/contract/detail/none.hpp>
|
||||
#include <boost/contract/detail/name.hpp>
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, arity_compl, f) \
|
||||
/* PRIVATE */
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, \
|
||||
arity, arity_compl, function_name) \
|
||||
template< \
|
||||
class BOOST_CONTRACT_DETAIL_NAME1(B), \
|
||||
class BOOST_CONTRACT_DETAIL_NAME1(C) \
|
||||
@@ -40,7 +46,7 @@
|
||||
boost::contract::detail::none&) \
|
||||
) { \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(obj)-> \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(B)::f( \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(B)::function_name( \
|
||||
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(args)) \
|
||||
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
|
||||
@@ -49,38 +55,66 @@
|
||||
}
|
||||
|
||||
#if BOOST_CONTRACT_DETAIL_TVARIADIC
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(f) \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, f)
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(function_name) \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, function_name)
|
||||
#else
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(f) \
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(function_name) \
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, f) \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, function_name) \
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, f) \
|
||||
#define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, \
|
||||
function_name) \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, \
|
||||
BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), f)
|
||||
BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), function_name)
|
||||
#endif
|
||||
|
||||
/* PUBLIC */
|
||||
/* PUBLIC */
|
||||
|
||||
#define BOOST_CONTRACT_NAMED_OVERRIDE(name, f) \
|
||||
#define BOOST_CONTRACT_NAMED_OVERRIDE(override_name, function_name) \
|
||||
struct name { \
|
||||
BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION( \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(has_member_function), f) \
|
||||
\
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(f) \
|
||||
BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \
|
||||
function_name \
|
||||
) \
|
||||
BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(function_name) \
|
||||
};
|
||||
#else
|
||||
// Empty type (not actually used) just needed to compile user contract code.
|
||||
#define BOOST_CONTRACT_NAMED_OVERRIDE(name, f) struct name {};
|
||||
/**
|
||||
Declare override type allowing to explicitly specify its name.
|
||||
Declare override type to be passed as an explicit template parameter to
|
||||
@RefFunc{boost::contract::public_function} for overriding public functions.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param override_name Name of override type to be declared.
|
||||
@param function_name Name of the overriding public function. This macro
|
||||
is called just once even if the function name is
|
||||
overloaded and the same override type can be used
|
||||
for all overloaded functions (see
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
*/
|
||||
#define BOOST_CONTRACT_NAMED_OVERRIDE(override_name, function_name) \
|
||||
struct name {}; /* empty type (not used) just to compile code */
|
||||
#endif
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDE(f) \
|
||||
BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, f), f)
|
||||
/**
|
||||
Declare override type naming it <c>override_<e>function_name</e></c>.
|
||||
Declare override type to be passed as an explicit template parameter to
|
||||
@RefFunc{boost::contract::public_function} for overriding public functions.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param function_name Name of the overriding public function. This macro
|
||||
is called just once even if the function name is
|
||||
overloaded and the same override type can be used
|
||||
for all overloaded functions (see
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
*/
|
||||
#define BOOST_CONTRACT_OVERRIDE(function_name) \
|
||||
BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, function_name), \
|
||||
function_name)
|
||||
|
||||
#if BOOST_CONTRACT_DETAIL_TVARIADIC
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
@@ -88,11 +122,23 @@
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
#define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, f) \
|
||||
BOOST_CONTRACT_OVERRIDE(f)
|
||||
/** @cond */
|
||||
#define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, function_name) \
|
||||
BOOST_CONTRACT_OVERRIDE(function_name)
|
||||
/** @endcond */
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
/**
|
||||
Declare multiple override types at once naming them <c>override_...</c>.
|
||||
This is a variadic macro, call @RefMacro{BOOST_CONTRACT_OVERRIDE} multiple
|
||||
times on compilers that do not support variadic macros instead.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param ... A comma separated list of one or more names of overriding
|
||||
public functions. This macro is provided for convenience, it is
|
||||
equivalent to calling @RefMacro{BOOST_CONTRACT_OVERRIDE} for
|
||||
each specified function name.
|
||||
*/
|
||||
#define BOOST_CONTRACT_OVERRIDES(...) \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \
|
||||
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
|
||||
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
|
||||
|
||||
/** @file
|
||||
Program contracts for public member functions.
|
||||
Different overloads are provided to handle static, virtual void/non-void, and
|
||||
overriding void/non-void public functions.
|
||||
*/
|
||||
|
||||
// TODO: Document that even with variadic templates there's a hard limit to function max args (18 works, but MAX_ARGS=19 does not). This limit comes from Boost.MPL (vector, push_back, etc.), Boost.FunctionTypes, and other Boost algorithm that do not currently have a variadic template implementation. However, re-impl all these Boost alg would be too much work for this lib, plus the 19 max args limit seems high enough, and it would eventually be removed if Boost.MPL, Boost.FunctionTypes are ever ported to impl that use variadic templates.
|
||||
|
||||
// TODO: Document that not using variadic templates (i.e., using pp meta-programming impl instead) does not increase compilation times (I measured this with the max_arg test program).
|
||||
@@ -51,7 +57,20 @@ namespace boost { namespace contract {
|
||||
// However, R is never specified, not even for virtual functions, when the
|
||||
// return type is void (i.e., R always optional).
|
||||
|
||||
// For static public functions.
|
||||
/**
|
||||
Program contracts for static public functions.
|
||||
Used to specify preconditions, postconditions, old value assignments, and check
|
||||
static class invariants for static public functions.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@tparam C Class of contracted member function. This template parameter must
|
||||
be explicitly specified for static public functions (because they
|
||||
have no object so this template parameter cannot be automatically
|
||||
deduced).
|
||||
@return The result of this function must be assigned to a local variable of type
|
||||
@RefClass{boost::contract::guard} declared at the beginning of the
|
||||
static public function definition (after declaring old value pointers
|
||||
if they are present).
|
||||
*/
|
||||
template<class C>
|
||||
set_precondition_old_postcondition<> public_function() {
|
||||
#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
|
||||
@@ -62,7 +81,22 @@ set_precondition_old_postcondition<> public_function() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// For non-static, non-virtual, and non-overriding public functions.
|
||||
/**
|
||||
Program contracts for non-static, non-virtual, and not overriding public
|
||||
functions.
|
||||
Used to specify preconditions, postconditions, old value assignments, and to
|
||||
check class invariants for public functions that are not static, not virtual,
|
||||
and do not override.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param obj The public function's object @c this. It will be @c const and/or
|
||||
@c volatile depending on the cv-qualifier for the contracted public
|
||||
function (volatile public functions will check volatile class
|
||||
invariants, see also @RefSect{advanced_topics, Advanced Topics}).
|
||||
@return The result of this function must be assigned to a local variable of type
|
||||
@RefClass{boost::contract::guard} declared at the beginning of the
|
||||
static public function definition (after declaring old value pointers
|
||||
if they are present).
|
||||
*/
|
||||
template<class C>
|
||||
set_precondition_old_postcondition<> public_function(C* obj) {
|
||||
#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
|
||||
@@ -95,6 +129,8 @@ set_precondition_old_postcondition<> public_function(C* obj) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
|
||||
// To use within macro expansions instead of defined(...) (PRIVATE macro).
|
||||
#ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
|
||||
#define BOOST_CONTRACT_PUBLIC_FUNCTIONS_ 0
|
||||
@@ -158,8 +194,65 @@ set_precondition_old_postcondition<> public_function(C* obj) {
|
||||
) \
|
||||
}
|
||||
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 0)
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 1)
|
||||
/** @endcond */
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Program contracts for virtual but not overriding public functions returning
|
||||
void.
|
||||
Used to specify preconditions, postconditions, old value assignments, and
|
||||
to check class invariants for public functions that are virtual, do not
|
||||
override, and return @c void.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param v The contracted virtual function extra trailing parameter of type
|
||||
@RefClass{boost::contract::virtual_}<c>*</c> and with default
|
||||
value @c 0.
|
||||
@param obj The public function's object @c this. It will be @c const and/or
|
||||
@c volatile depending on the cv-qualifier for the contracted
|
||||
public function (volatile public functions will check volatile
|
||||
class invariants, see also
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
@return The result of this function must be assigned to a local variable of
|
||||
type @RefClass{boost::contract::guard} declared at the beginning of
|
||||
the static public function definition (after declaring old value
|
||||
pointers if they are present).
|
||||
*/
|
||||
template<class C>
|
||||
set_precondition_old_postcondition<> public_function(virtual_* v, C* obj);
|
||||
|
||||
/**
|
||||
Program contracts for virtual but not overriding public functions returning
|
||||
non-void.
|
||||
Used to specify preconditions, postconditions, old value assignments, and
|
||||
to check class invariants for public functions that are virtual, do not
|
||||
override, and do not return @c void.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param v The contracted virtual function extra trailing parameter of type
|
||||
@RefClass{boost::contract::virtual_}<c>*</c> and with default
|
||||
value @c 0.
|
||||
@param r A reference to the contracted virtual function return value.
|
||||
(This could be a variable local to the contracted function
|
||||
scope, but it must be set by programmers at each function
|
||||
@c return statement.)
|
||||
@param obj The public function's object @c this. It will be @c const and/or
|
||||
@c volatile depending on the cv-qualifier for the contracted
|
||||
public function (volatile public functions will check volatile
|
||||
class invariants, see also
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
@return The result of this function must be assigned to a local variable of
|
||||
type @RefClass{boost::contract::guard} declared at the beginning of
|
||||
the static public function definition (after declaring old value
|
||||
pointers if they are present).
|
||||
*/
|
||||
template<typename R, class C>
|
||||
set_precondition_old_postcondition<R> public_function(
|
||||
virtual_* v, R& r, C* obj);
|
||||
#else
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 0)
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 1)
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
|
||||
// For non-static, virtual, and overriding public functions (PRIVATE macro).
|
||||
#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
|
||||
@@ -234,7 +327,87 @@ BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 1)
|
||||
) \
|
||||
}
|
||||
|
||||
#if BOOST_CONTRACT_DETAIL_TVARIADIC
|
||||
/** @endcond */
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
Program contracts for overriding (virtual or not) public functions returning
|
||||
void.
|
||||
Used to specify preconditions, postconditions, old value assignments, and
|
||||
to check class invariants for public functions that are virtual, do not
|
||||
override, and return @c void.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param v The contracted virtual function extra trailing parameter of type
|
||||
@RefClass{boost::contract::virtual_}<c>*</c> and with default
|
||||
value @c 0.
|
||||
@param f A pointer to the contracted function.
|
||||
@param obj The public function's object @c this. It will be @c const and/or
|
||||
@c volatile depending on the cv-qualifier for the contracted
|
||||
public function (volatile public functions will check volatile
|
||||
class invariants, see also
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
@param args The contracted function formal parameters (by reference and in
|
||||
the oder they appear in the contracted function declaration).
|
||||
On compilers that do not support variadic templates, this
|
||||
library internally implements this function using preprocessor
|
||||
meta-programming (in this case, the maximum number of supported
|
||||
arguments @p args is defined by
|
||||
@RefMacro{BOOST_CONTRACT_MAX_ARGS}).
|
||||
@tparam O The overriding type @c override_... declared invoking the
|
||||
@RefMacro{BOOST_CONTRACT_OVERRIDE} (or similar) macro with the
|
||||
contracted function name. This template parameter must be
|
||||
explicitly specified (because it is not used in this function
|
||||
formal parameter so it cannot be automatically deduced).
|
||||
@return The result of this function must be assigned to a local variable of
|
||||
type @RefClass{boost::contract::guard} declared at the beginning of
|
||||
the static public function definition (after declaring old value
|
||||
pointers if they are present).
|
||||
*/
|
||||
template<class O, typename F, class C, typename... Args>
|
||||
set_precondition_old_postcondition<> public_function(
|
||||
virtual_* v, F f, C* obj, Args&... args);
|
||||
|
||||
/**
|
||||
Program contracts for overriding (virtual or not) public functions returning
|
||||
non-void.
|
||||
Used to specify preconditions, postconditions, old value assignments, and
|
||||
to check class invariants for public functions that are virtual, do not
|
||||
override, and do not return @c void.
|
||||
@see @RefSect{tutorial, Tutorial}.
|
||||
@param v The contracted virtual function extra trailing parameter of type
|
||||
@RefClass{boost::contract::virtual_}<c>*</c> and with default
|
||||
value @c 0.
|
||||
@param r A reference to the contracted virtual function return value.
|
||||
(This could be a variable local to the contracted function
|
||||
scope, but it must be set by programmers at each function
|
||||
@c return statement.)
|
||||
@param f A pointer to the contracted function.
|
||||
@param obj The public function's object @c this. It will be @c const and/or
|
||||
@c volatile depending on the cv-qualifier for the contracted
|
||||
public function (volatile public functions will check volatile
|
||||
class invariants, see also
|
||||
@RefSect{advanced_topics, Advanced Topics}).
|
||||
@param args The contracted function formal parameters (by reference and in
|
||||
the oder they appear in the contracted function declaration).
|
||||
On compilers that do not support variadic templates, this
|
||||
library internally implements this function using preprocessor
|
||||
meta-programming (in this case, the maximum number of supported
|
||||
arguments @p args is defined by
|
||||
@RefMacro{BOOST_CONTRACT_MAX_ARGS}).
|
||||
@tparam O The overriding type @c override_... declared invoking the
|
||||
@RefMacro{BOOST_CONTRACT_OVERRIDE} (or similar) macro with the
|
||||
contracted function name. This template parameter must be
|
||||
explicitly specified (because it is not used in this function
|
||||
formal parameter so it cannot be automatically deduced).
|
||||
@return The result of this function must be assigned to a local variable of
|
||||
type @RefClass{boost::contract::guard} declared at the beginning of
|
||||
the static public function definition (after declaring old value
|
||||
pointers if they are present).
|
||||
*/
|
||||
template<class O, typename R, typename F, class C, typename... Args>
|
||||
set_precondition_old_postcondition<R> public_function(
|
||||
virtual_* v, R& r, F f, C* obj, Args&... args);
|
||||
#elif BOOST_CONTRACT_DETAIL_TVARIADIC
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1,
|
||||
/* arity = */ ~, /* arity_compl = */ ~, /* has_result = */ 0)
|
||||
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1,
|
||||
|
||||
Reference in New Issue
Block a user