finished reviewing first draft of reference section

This commit is contained in:
Lorenzo Caminiti
2016-05-30 10:36:52 -07:00
parent 3fef54b33e
commit 128a42c004
38 changed files with 1794 additions and 1511 deletions

View File

@@ -8,7 +8,21 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Include all header files required by this library at once.
Include all header files required by this library at once (for convenience).
All headers file <c>boost/contract/\*.hpp</c> are independent from one another
and can be included one-by-one to reduce the amount of the code of this library
being compiled in user code (but that should not make a significant difference).
Instead the headers <c>boost/contract/core/\*.hpp</c> are not independent from
other library headers and they are automatically included by the
<c>boost/contract/\*.hpp</c> headers (so the <c>boost/contract/core/\*.hpp</c>
headers are usually not directly included by programmers).
All files under the <c>boost/contract/detail/</c> directory, names within the
@c boost::contract::detail namespace, names prefixed with
@c boost_contract_detail... and @c BOOST_CONTRACT_DETAIL... (in any namesapce,
including user's code) are reserved for internal use of this library and should
never be used directly by programmers.
@see @RefSect{getting_started, Getting Started}
*/
#include <boost/contract/detail/all_core_headers.hpp>

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Facilities to assert contract conditions.
Facility to assert contract conditions.
*/
#include <boost/contract/detail/all_core_headers.hpp>
@@ -27,17 +27,24 @@ Facilities to assert contract conditions.
#else
/**
Preferred way to assert contract conditions.
Any exception thrown from within a preconditions, postcondition, and
Any exception thrown from within a preconditions, postcondition, or
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
exceptions from the precondition, postcondition, or invariant functions when
the asserted condition is checked to be @c false (this library will then
call the appropriate contract failure handler
@RefFunc{boost::contract::precondition_failure}, etc.).
However, using this macro is preferred because in case @p 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}.
file name (<c>__FILE__</c>), line number (<c>__LINE__</c>), and asserted
condition source code so to produce an informative error message.
This macro is not a variadic macro. Therefore, if @p condition contains
commas not already wrapped by round parenthesis, it needs to be wrapped by
an outer set of extra round parenthesis <c>BOOST_CONTRACT_ASSERT((...))</c>
(as usual with C++ non-variadic macro parameters).
@see @RefSect{tutorial, Tutorial}
@param condition The contract condition being checked.
*/
#define BOOST_CONTRACT_ASSERT(condition) /* nothing */

View File

@@ -10,7 +10,7 @@
// 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
Facilities to specify base classes so to support subcontracting.
Facility to specify inheritance form base classes (to support subcontracting).
*/
#include <boost/contract/detail/all_core_headers.hpp>
@@ -24,16 +24,21 @@ 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.
Used to program a @c typedef listing the bases of a derived class.
In order to support subcontracting, a derived class that specifies contracts for
one or more overriding public function must declare a @c typedef named
@RefMacro{BOOST_CONTRACT_BASE_TYPEDEF} using this macro.
This @c typedef must be @c public unless @RefClass{boost::contract::access} is
used.
This is a variadic macro. On compilers that do not support variadic macros, the
base classes @c typedef can be programmed manually without using this macro (see
@RefSect{advanced_topics, Advanced Topics}).
@see @RefSect{tutorial, Tutorial}
@param ... Comma separated list of base classes. Each listed base must
explicitly list its access specifier @c public, @c protected, or
@c private, and @c virtual if present (this not always required in
C++ instead).
*/
#define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Statically disable execution but also compilation of functor calls.
Statically disable compilation and execution of functor calls.
*/
// Do not include all_core_headers here (call_if is essentially standalone).
@@ -40,16 +40,20 @@ Statically disable execution but also compilation of functor calls.
namespace boost { namespace contract {
/**
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.
Class template to select compilation and execution of functor calls via a static
boolean condition.
This class template has no members because it is never used directly, it is only
used via its specializations.
Usually this class template is instantiated only via the return value of
@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
@see @RefSect{advanced_topics, Advanced Topics}
@tparam Cond Static boolean condition controlling functor calls.
@tparam Cond Static boolean condition selecting which functor call to compile
and execute.
@tparam Then Type of functor to call when the static condition if true.
@tparam R Return type of then-branch functor.
@tparam ThenResult Return type of then-branch functor call.
*/
template<bool Cond, typename Then, typename R =
template<bool Cond, typename Then, typename ThenResult =
#ifndef DOXYGEN
boost::contract::detail::none
#else
@@ -61,14 +65,16 @@ struct call_if_statement {}; // Empty so cannot be used (but copyable).
/**
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.
The base class is a call-if statement so the else and else-if statements can be
specified if needed.
Usually this class template is instantiated only via the return value of
@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
@note The <c>result_of<Then()>::type</c> expression should be evaluated only
when the static condition is already checked to be true (because
@c Then() is required to compile only in that case). This template
specialization introduces an extra level of indirection necessary for
the proper lazy evaluation of this result-of expression.
@see @RefSect{advanced_topics, Advanced Topics}
@tparam Then Type of functor to call when the static condition if true.
*/
@@ -90,10 +96,12 @@ struct call_if_statement<true, Then,
{ // 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.
@param f Then-branch nullary templated functor. The functor @c f() is
compiled and called in this case (because the if-statement
static condition is true for this template specialization). The
return type of @c f() must be the same as (or implicitly
convertible to) the return type of all other functor calls
specified for this call-if object.
*/
explicit call_if_statement(Then f) : call_if_statement<true, Then,
BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>(f) {}
@@ -101,94 +109,92 @@ struct call_if_statement<true, Then,
/**
Template specialization to handle true static conditions for then-branch functor
calls returning non-void.
calls that do not return @c void.
Usually this class template is instantiated only via the return value of
@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
@see @RefSect{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.
@tparam ThenResult Non-void return type of the then-branch functor call.
*/
template<typename Then, typename R>
struct call_if_statement<true, Then, R> { // Copyable (as *).
template<typename Then, typename ThenResult>
struct call_if_statement<true, Then, ThenResult> { // 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.
@param f Then-branch nullary templated functor. The functor call @c f()
is compiled and executed in this case (because the if-statement
static condition is true for this template specialization). The
return type of @c f() must be the same as (or implicitly
convertible to) the @p ThenResult type.
*/
explicit call_if_statement(Then f) : r_(boost::make_shared<R>(f())) {}
explicit call_if_statement(Then f) :
r_(boost::make_shared<ThenResult>(f())) {}
/** 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_; }
/**
This implicit type conversion returns a copy of the value returned by the
call to the then-branch functor.
*/
operator ThenResult() 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.
@param f Else-branch nullary templated functor. The functor call @c f()
is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be the same as
(or implicitly convertible to) the @p ThenResult type.
@return A copy of the value returned by the call to the then-branch functor
(because the else-branch functor call is not executed in this case).
*/
template<typename Else>
R const& else_(Else const& f) const { return *r_; }
ThenResult 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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be the same as
(or implicitly convertible to) the @p ThenResult type.
@tparam ElseIfCond Static boolean condition selecting which functor call to
compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately it will return the
return value of the then-branch functor call in this case (because
the if-statement static condition is true for this template
specialization).
*/
template<bool ElseIfCond, typename ElseIfThen>
call_if_statement<true, Then, R> else_if_c(ElseIfThen const& f) const {
return *this;
}
call_if_statement<true, Then, ThenResult> 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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be the same as
(or implicitly convertible to) the @p ThenResult type.
@tparam ElseIfCond Static boolean nullary meta-function selecting which
functor call to compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately it will return the
return value of the then-branch functor call in this case (because
the if-statement static condition is true for this template
specialization).
*/
template<class ElseIfCond, typename ElseIfThen>
call_if_statement<true, Then, R> else_if(ElseIfThen const& f) const {
return *this;
}
call_if_statement<true, Then, ThenResult> else_if(ElseIfThen const& f)
const { return *this; }
private:
boost::shared_ptr<R> r_;
boost::shared_ptr<ThenResult> r_;
};
/**
Template specialization to handle true static conditions for then-branch functor
calls returning void.
calls that return @c void.
Usually this class template is instantiated only via the return value of
@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
@see @RefSect{advanced_topics, Advanced Topics}
@tparam Then Type of functor to call when the static condition if true.
*/
@@ -196,37 +202,43 @@ 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.
@param f Then-branch nullary templated functor. The functor call @c f()
is compiled and executed in this case (because the if-statement
static condition is true for this template specialization). The
return type of @c f() must be @c void in this case (because the
then-branch functor calls return @c void for this template
specialization).
*/
explicit call_if_statement(Then f) { f(); }
// Cannot provide `operator R()` here, because R is void.
// Cannot provide `operator ThenResult()` here, because ThenResult 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.
@param f Else-branch nullary templated functor. The functor call @c f()
is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be @c void in
this case (because the then-branch functor calls return @c void
for this template specialization).
*/
template<typename Else>
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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be @c void in
this case (because the then-branch functor calls return @c void
for this template specialization).
@tparam ElseIfCond Static boolean condition selecting which functor call to
compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately it will return
@c void in this case (because the then-branch functor calls return
@c void for this template specialization).
*/
template<bool ElseIfCond, typename ElseIfThen>
call_if_statement<true, Then, void> else_if_c(ElseIfThen const& f) const {
@@ -235,16 +247,18 @@ struct call_if_statement<true, Then, void> { // Copyable (no data).
/**
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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is never compiled and executed in this case (because the
if-statement static condition is true for this template
specialization). The return type of @c f() must be @c void in
this case (because the then-branch functor calls return @c void
for this template specialization).
@tparam ElseIfCond Static boolean nullary meta-function selecting which
functor call to compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately it will return
@c void in this case (because the then-branch functor calls return
@c void for this template specialization).
*/
template<class ElseIfCond, typename ElseIfThen>
call_if_statement<true, Then, void> else_if(ElseIfThen const& f) const {
@@ -254,8 +268,11 @@ struct call_if_statement<true, Then, void> { // Copyable (no data).
/**
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.
This one specialization handles all else-branch functor calls (whether they
return @c void or not).
Usually this class template is instantiated only via the return value of
@RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
@see @RefSect{advanced_topics, Advanced Topics}
@tparam Then Type of functor to call when the static condition if true.
*/
@@ -269,11 +286,12 @@ struct call_if_statement<false, Then,
> {
/**
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.
@param f Then-branch nullary templated functor. The functor call @c f()
is never compiled and executed in this case (because the
if-statement static condition is false for this template
specialization). The return type of @c f() must be the same as
(or implicitly convertible to) the return type of the other
functor calls specified for this call-if object.
*/
explicit call_if_statement(Then const& f) {}
@@ -281,15 +299,19 @@ struct call_if_statement<false, Then,
/**
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.
@note The <c>result_of<Else()>::type</c> expression 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,
this result-of expression is evaluated lazily only in
instantiations of this template.
@param f Else-branch nullary templated functor. The functor call @c f()
is compiled and executed in this case (because the if-statement
static condition is @c false for this template specialization).
The return type of @c f() must be the same as (or implicitly
convertible to) the return type of the other functor calls
specified for this call-if object.
@return A copy of the value returned by the call to the else-branch functor
@c f().
*/
template<typename Else>
#ifndef DOXYGEN
@@ -301,15 +323,18 @@ struct call_if_statement<false, Then,
/**
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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is compiled and executed if and only if @c ElseIfCond is
@c true (because the if-statement static condition is @c false
for this template specialization). The return type of @c f()
must be the same as (or implicitly convertible to) the return
type of the other functor calls specified for this call-if
object.
@tparam ElseIfCond Static boolean condition selecting which functor call to
compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately this 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 {
@@ -318,16 +343,18 @@ struct call_if_statement<false, Then,
/**
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.
@param f Else-if-branch nullary templated functor. The functor call
@c f() is compiled and executed if and only if
@c ElseIfCond::value is @c true (because the if-statement static
condition is false for this template specialization). The return
type of @c f() must be the same as (or implicitly convertible
to) the return type of the other functor calls specified for
this call-if object.
@tparam ElseIfCond Static boolean nullary meta-function selecting which
functor call to compile and execute.
@return A call-if statement so the else statement and additional else-if
statements can be specified if needed. Ultimately this 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)
@@ -337,15 +364,20 @@ struct call_if_statement<false, Then,
};
/**
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
Select compilation and execution of functor calls via a static boolean
condition.
Make a call-if object with the specified then-branch functor.
@see @RefSect{advanced_topics, Advanced Topics}
@param f Then-branch nullary templated functor. The functor call @c f() is
compiled and executed if and only if @c Cond if @c true. The return
type of other functor calls specified for this call-if statement
(else-branches, else-if-branches, etc.) must be the same as (or
implicitly convertible to) the return type of then-branch functor
call @c f().
@tparam Cond Static boolean condition selecting which functor call to compile
and execute.
@return A call-if statement so else and else-if statements can be specified if
needed. Ultimately this will return the return value of the
functor call being compiled and executed.
*/
template<bool Cond, typename Then>
@@ -354,15 +386,20 @@ call_if_statement<Cond, Then> call_if_c(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
Select compilation and execution of functor calls via a static boolean nullary
meta-function.
Make a call-if object with the specified then-branch functor.
@see @RefSect{advanced_topics, Advanced Topics}
@param f Then-branch nullary templated functor. The functor call @c f() is
compiled and executed if and only if @c Cond::value if @c true. The
return type of other functor calls specified for this call-if
statement (else-branches, else-if-branches, etc.) must be the same
as (or implicitly convertible to) the return type of then-branch
functor call @c f().
@tparam Cond Static boolean nullary meta-function selecting which functor
call to compile and execute.
@return A call-if statement so else and else-if statements can be specified if
needed. Ultimately this will return the return value of the
functor call being compiled and executed.
*/
template<class Cond, typename Then>
@@ -371,31 +408,39 @@ call_if_statement<Cond::value, Then> call_if(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).
Select compilation and execution of a boolean functor check via a static boolean
condition.
Compile and execute a boolean nullary functor call if and only if the specified
static condition is true, otherwise trivially return @c true.
@see @RefSect{advanced_topics, Advanced Topics}
@param f Boolean nullary templated functor. The functor call @c f() is
compiled and executed if and only if @c Cond is @c true.
@tparam Cond Static boolean condition selecting when the functor call should
be compiled and executed.
@return Boolean value returned by @c f() if the 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) {
template<bool Cond, typename Check>
bool check_if_c(Check 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).
Select compilation and execution of a boolean functor check via a static boolean
nullary meta-function.
Compile and execute a boolean nullary functor call if and only if the specified
static condition is true, otherwise trivially return @c true.
@see @RefSect{advanced_topics, Advanced Topics}
@param f Boolean nullary templated functor. The functor call @c f() is
compiled and executed if and only if @c Cond::value is @c true.
@tparam Cond Static boolean nullary meta-function selecting when the functor
call should be compiled and executed.
@return Boolean value returned by @c f() if the static condition if true,
otherwise simply return @c true (i.e., check trivially passed).
*/
template<class Cond, typename F>
bool check_if(F f) {
template<class Cond, typename Check>
bool check_if(Check f) {
return call_if_c<Cond::value>(f).else_(
boost::contract::detail::always_true());
}

View File

@@ -24,57 +24,68 @@ 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.
This is used to specify postconditions, old value assignments at body, and
check class invariants for constructors (see
@RefClass{boost::contract::constructor_precondition} to specify preconditions
for constructors instead).
For optimization, this can be omitted for constructors that do not have
postconditions when the enclosing class has no invariants.
@see @RefSect{tutorial, Tutorial}
@param obj The object @c this from the scope of the contracted constructor.
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the body
of the contracted constructor (otherwise this library will generate a
run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class C>
set_old_postcondition<> constructor(C* obj) {
// Must #if also on ..._PRECONDITIONS here because set_... is generic.
template<class Class>
specify_old_postcondition<> constructor(Class* obj) {
// Must #if also on ..._PRECONDITIONS here because specify_... is generic.
#if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS)
return set_old_postcondition<>(
new boost::contract::detail::constructor<C>(obj));
return specify_old_postcondition<>(
new boost::contract::detail::constructor<Class>(obj));
#else
return set_old_postcondition<>();
return specify_old_postcondition<>();
#endif
}
// 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).
/**
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.
Program preconditions for constructors.
This class must be the very first base class of the contracted class. Also the
contracted class shall privately inherit from this base class (to not alter the
contracted class public interface).
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
Unions cannot have base classes in C++ so this class can be used to declare a
local object within the constructor function just before
@RefFunc{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).
@see @RefSect{tutorial, Tutorial}
@tparam Class Class of contracted constructor.
*/
template<class C>
class constructor_precondition { // Copyable (no data).
template<class Class>
class constructor_precondition { // Copyable (has no data).
public:
/** Construct this object for constructor that do not have preconditions. */
/**
Construct this object without specifying constructor preconditions.
This is implicitly called for those constructors of the contracted class
that do not specify 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.
Construct this object specifying constructor preconditions.
@param f Functor called by this library to check constructor
preconditions @c f(). Precondition assertions within this
functor call are usually programmed using
@RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
call to this functor indicates a precondition failure (and will
result in this library calling
@RefFunc{boost::contract::precondition_failure}). This functor
must be a nullary functor. This functor can capture variables by
value, or better by (constant) reference to avoid extra copies.
*/
template<typename F>
explicit constructor_precondition(F const& f) {

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Used to declare invariants, base types, etc private members.
Facility to declare invariants, base types, etc all as private members.
*/
#include <boost/contract/core/config.hpp>
@@ -23,6 +23,7 @@ Used to declare invariants, base types, etc private members.
#include <boost/function_types/property_tags.hpp>
#include <boost/mpl/vector.hpp>
#endif
#include <boost/noncopyable.hpp>
// TODO: Review all warnings for examples, tests, and also lib compilation...
@@ -45,18 +46,27 @@ namespace boost {
namespace boost { namespace contract {
/**
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.
Friend this class to declare invariants and base types as private members.
Declare this class as friend of the contracted class in order to declare
the invariants functions and the base types @c typedef as non-public members.
In real code, programmers will likely chose to declare this class as friend so
to fully control the contracted class public interface.
This class is not intended to be directly used by programmers a part from
declaring it @c friend (and that is why this class does not have any public
member and it is not copyable).
@note Not making this class friend of the contracted class will cause
compiler errors on some compilers (e.g., MSVC) because the private
members needed to check the contracts will not be accessible. On other
compilers (e.g., GCC and CLang), the private access will instead fail
SFINAE and no compiler error will be reported while invariants and
subcontracting will be silently skipped at run-time. Therefore,
programmers must make sure to either declare invariant functions and
base types @c typedef as public members or to make this class a friend.
@see @RefSect{advanced_topics, Advanced Topics}
*/
class access { // Copyable (as shell with no data member).
class access : private boost::noncopyable {
/** @cond */
// No public APIs (so users cannot use it directly by mistake).

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Configuration macros.
Facilities to configure this library compile-time and run-time behaviour.
*/
// IMPORTANT: This header MUST NOT #include any other header of this lib.
@@ -22,32 +22,37 @@ Configuration macros.
/**
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}.
In general, this library must be compiled as a shared library (a.k.a.,
Dynamically Linked Library (DLL)) by defining this macro. That is necessary
when the same library instance is used by multiple programs (otherwise the
contracts will not necessarily be checked correctly at run-time).
@b Rationale: 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).
Define this macro when compiling user code to avoid compiling this library
(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}.
separately from user code. This library headers are simply included in the
user program and this library implementation code is compiled 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 it is used by
multiple programs (otherwise the contracts will not necessarily be checked
correctly at run-time).
@b Rationale: Named after @c BOOST_CHRONO_HEADER_ONLY.
@see @RefSect{getting_started, Getting Started}
*/
#define BOOST_CONTRACT_HEADER_ONLY
#endif
// TODO: Document that no code should in general be programmed before the contract in function definitions, but for example mutex locks can be programmed before contracts if necessary for synchronization.
#ifdef DOXYGEN
/**
Define this macro to not lock internal library data for thread safety
@@ -55,13 +60,13 @@ Configuration macros.
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
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}.
also to safely access the failure handler functors) and that could introduce
a significant amount of synchronization in some multi-threaded applications.
@b Rationale: Named after @c BOOST_DISABLE_THREADS.
@see @RefSect{contract_programming_overview, Contract Programming Overview}
*/
#define BOOST_CONTRACT_DISABLE_THREADS
#endif
@@ -70,17 +75,19 @@ Configuration macros.
/**
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.
On compilers that support variadic macros, this macro has no effect.
On compilers that do not support variadic macros, this macro can be defined
to support a maximum number of arguments different than @c 10 for
overriding public functions (contracted via
@RefFunc{boost::contract::public_function}).
@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
for overriding public functions (because of similar limits for 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.
@b Rationale: Named after @c BOOST_FUNCTION_MAX_ARGS.
@see @RefSect{tutorial, Tutorial}
*/
#define BOOST_CONTRACT_MAX_ARGS 10
#endif
@@ -88,102 +95,122 @@ Configuration macros.
#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).
This macro can be defined if the @c typedef declared using
@RefMacro{BOOST_CONTRACT_BASE_TYPES} must have a name different than
@c base_types.
@b Rationale: This macro cannot be called @c BOOST_CONTRACT_BASE_TYPES
because that is already the name of the macro that extracts
public bases. Then @c BOOST_CONTRACT_BASE_TYPEDEF is a
reasonable name (but without changing this macro default
definition to @c base_typedef because @c base_types is
remains the preferred syntax for user code).
@see @RefSect{tutorial, Tutorial}
*/
#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 the name of the invariant member functions (@c invariant by defult).
This macro expands to the name of the @c const and <c>const volatile</c>
member functions that check mutable and volatile class invariants
respectively. This macro can be defined if the invariant functions need to
be named differently from @c invariant.
@see @RefSect{tutorial, Tutorial}
*/
#define BOOST_CONTRACT_INVARIANT invariant
#endif
#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 the name of the static invariant member function (@c static_invariant
by defult).
This macro expands to the name of the @c static member function that checks
static class invariants. This macro can be defined if the static invariant
function needs to be named differently from @c static_invariant.
@b Rationale: C++ does not allow to overload member functions based on the
@c static classifier, so a name different from the one
expanded by @RefMacro{BOOST_CONTRACT_INVARIANT} needed to be
used here.
@see @RefSect{tutorial, Tutorial}
*/
#define BOOST_CONTRACT_STATIC_INVARIANT static_invariant
#endif
#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,
Disable a number of static checks and related compile-time errors generated
by this library (undefined by default).
Among other compile-time errors, defining this macro disables compile-time
error for the following checks:
@li The static invariant member function must be @c static.
@li Non-static invariant member functions must be 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.
@li A class that programs contracts for one or more overriding public
functions via @RefFunc{boost::contract::public_function} must also
define the @RefMacro{BOOST_CONTRACT_BASE_TYPES} @c typedef.
*/
#define BOOST_CONTRACT_PERMISSIVE
#endif
#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.
Code block to execute if contracts are not assigned to a
@RefClass{boost::contract::guard} variable (undefined by default).
In general, there is a logic error in the program when contracts are not
assigned to a local variable of type @RefClass{boost::contract::guard}.
Therefore, by default (i.e., when this macro is not defined) this library
calls @c assert with a @c false condition in such cases. If this macro is
defined, this library will execute the code expanded by the macro instead of
calling @c assert (if programmers prefer to throw an exception, etc.).
*/
#define OOST_CONTRACT_ON_MISSING_GUARD
#define BOOST_CONTRACT_ON_MISSING_GUARD
#endif
#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 this macro to not disable other any assertion checking while checking
preconditions (undefined by default).
The @RefSect{bibliography, [N1962]} proposal does not disable any assertion
checking while checking preconditions (because unchecked arguments can be
passed to function bodies if contract checking is disabled within
precondition checking when function bodies are executed directly or
indirectly to check the preconditions in question). However, not disabling
assertion checking while checking preconditions can lead to infinite
recursion in user code so by default this macro is not defined (but this
macro can be defined to obtain the behaviour specified in
@RefSect{bibliography, [1962]}).
@see @RefSect{contract_programming_overview, Contract Programming Overview}
*/
#define OOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
#define BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
#endif
#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}.
If this macro is defined, this library implementation code is also optimized
to reduce compile-time (not just run-time) overhead associated with checking
preconditions. Users can also manually program @c \#ifdef statements in
their code using this macro to completely disable compilation of
preconditions (not recommended).
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_PRECONDITIONS
#endif
#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}.
If defined, this library does not check postconditions and does not copy old
values at run-time (undefined by default).
If this macro is defined, this library implementation code is also optimized
to reduce compile-time (not just run-time) overhead associated with checking
postconditions and copying old values. Users can also manually program
@c \#ifdef statements in their code using this macro to completely disable
compilation of postconditions and old values (not recommended).
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_POSTCONDITIONS
#endif
@@ -193,15 +220,13 @@ Configuration macros.
/**
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).
If this macro is defined, this library implementation code is also optimized
to reduce compile-time (not just run-time) overhead associated with
checking class invariants at function entry.
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}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_ENTRY_INVARIANTS
#endif
@@ -209,17 +234,15 @@ Configuration macros.
#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
If defined, this library does not check exit invariants 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).
If this macro is defined, this library implementation code is also optimized
to reduce compile-time (not just run-time) overhead associated with
checking class invariants at function exit.
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}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_EXIT_INVARIANTS
#endif
@@ -230,16 +253,16 @@ Configuration macros.
/**
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).
If this macro is defined, this library implementation code is also optimized
to reduce compile-time (not just run-time) overhead associated with
checking class invariants (at both function entry and exit). Users can also
manually program @c \#ifdef statements in their code using this macro to
completely disable compilation of class invariants (not recommended).
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}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_INVARIANTS
#endif
@@ -252,19 +275,22 @@ Configuration macros.
#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
Defined by this library if constructor contracts are not being checked by
@RefFunc{boost::contract::constructor}.
Users can manually program @c \#ifdef statements in their code using this
macro to completely disable compilation of constructor contracts (not
recommended).
This macro is automatically defined 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},
programmers try to manually define this macro. Programmers 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}.
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead (constructor
preconditions are checked separately by
@RefClass{boost::contract::constructor_precondition} so they are disabled by
@RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}).
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_CONSTRUCTORS
#endif
@@ -274,16 +300,21 @@ Configuration macros.
#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
Defined by this library if destructor contracts are not being checked by
@RefFunc{boost::contract::destructor}.
Users can manually program @c \#ifdef statements in their code using this
macro to completely disable compilation of destructor contracts (not
recommended).
This macro is automatically defined 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},
programmers try to manually define this macro. Programmers 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}.
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead (destructors have no
preconditions, see also @RefSect{contract_programming_overview, Contract
Programming Overivew}).
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_DESTRUCTORS
#endif
@@ -294,16 +325,20 @@ Configuration macros.
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
Defined by this library if public function contracts are not being checked
by @RefFunc{boost::contract::public_function}.
Users can manually program @c \#ifdef statements in their code using this
macro to completely disable compilation of public function contracts (not
recommended).
This macro is automatically defined 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},
programmers try to manually define this macro. Programmers 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}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
#endif
@@ -313,15 +348,20 @@ Configuration macros.
#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
Defined by this library if non-member, private, and protected function
contracts are not being checked by @RefFunc{boost::contract::function}.
Users can manually program @c \#ifdef statements in their code using this
macro to completely disable compilation of non-member, private, and
protected function contracts (not recommended).
This macro is automatically defined 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}.
programmers try to manually define this macro. Programmers can manually
define @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} and
@RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} instead (private and protected
functions do not check class invariants, see also
@RefSect{contract_programming_overview, Contract Programming Overview}).
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_FUNCTIONS
#endif
@@ -333,16 +373,20 @@ Configuration macros.
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
Defined by this library if no contracts (for any operation) are being
checked.
Users can manually program @c \#ifdef statements in their code using this
macro to completely disable inclusion of this library headers, etc. (not
recommended).
This macro is automatically defined 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},
programmers try to manually define this macro. Programmers 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}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
#define BOOST_CONTRACT_NO_ALL
#endif

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Exception and utilities to report contract assertion failures.
Exceptions and other facilities to handle contract assertion failures.
*/
#include <boost/contract/detail/declspec.hpp>
@@ -23,50 +23,68 @@ Exception and utilities to report contract assertion failures.
// because user code might explicitly call precondition_failure() (for whatever
// reason...). Otherwise, the public API of this lib will change.
#ifdef DOXYGEN
// Needed for `std::` prefix to show (but remove via `EXCLUDE_SYMBOLS=std`).
namespace std {
class exception {};
class bad_cast {};
}
#endif
namespace boost { namespace contract {
/**
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}.
will (inheriting from @c std::exception, @c std::bad_cast, etc.).
@see @RefSect{advanced_topics, Advanced Topics}
*/
class BOOST_CONTRACT_DETAIL_DECLSPEC exception {
public:
/** Destruct this object. */
virtual ~exception() BOOST_NOEXCEPT_OR_NOTHROW;
/**
Destruct this object.
@b Throws: @c noexcept (or @c throw() if no C++11).
*/
virtual ~exception() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
};
/**
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.
Exception thrown when inconsistent return values are passed to overridden
virtual public functions.
This exception is internally thrown by this library when programmers specify
return values for overriding public functions in derived classes that are
inconsistent with the return types of the virtual public functions being
overridden from base classes.
<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}.
@b Rationale: 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.
Construct this object with the name of the from- and to- types.
@param from_type_name Name of the from-type (source).
@param to_type_name Name of the to-type (destination).
*/
explicit bad_virtual_result_cast(char const* from_type_name,
char const* to_type_name);
/** Destruct this object. */
virtual ~bad_virtual_result_cast() BOOST_NOEXCEPT_OR_NOTHROW;
/**
Destruct this object.
@b Throws: @c noexcept (or @c throw() if no C++11).
*/
virtual ~bad_virtual_result_cast()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/** Return an error description (containing both from and to type names). */
virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW;
/**
Description for this error (containing both from- and to- type names).
@b Throws: @c noexcept (or @c throw() if no C++11).
*/
virtual char const* what() const
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/** @cond */
private:
@@ -78,64 +96,77 @@ private:
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}.
This exception is typically used to report contract assertion failures because
it contains detailed information about the assertion file name, line number,
condition source code, etc. (so it provides detailed error messages), but any
other exception can be used to report a contract assertion failure. This library
will call the appropriate contract failure handler function
(@RefFunc{boost::contract::precondition_failure}, etc.) when this or any other
exception is thrown while checking contracts (by default, these failure handler
functions terminate the program but they can be customized to take any other
action).
@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).
Construct this object with the asserted condition file name, line number,
and source code text (all optional).
This constructor can also be used to specify no information (default
constructor), or to specify only file name and line number but not source
code text (because of 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.
@param code Text listing the source code of the asserted condition.
*/
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.
Construct this object with the asserted condition source code text only.
@param code Text listing the source code of the asserted condition.
*/
explicit assertion_failure(char const* const code);
/** Destruct this object. */
virtual ~assertion_failure() BOOST_NOEXCEPT_OR_NOTHROW;
/**
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).
Destruct this object.
@b Throws: @c noexcept (or @c throw() if no C++11).
*/
virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW;
virtual ~assertion_failure()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Return assertion file.
@return Return file as specified at construction (or @c "" if no file was
String describing the failed assertion.
@b Throws: @c noexcept (or @c throw() if no C++11).
@return A string formatted similarly to the following:
<c>assertion "`code()`" failed: file "`file()`", line \`line()\`</c>.
File, line, and code will be omitted from this string if they were
not specified at construction.
*/
virtual char const* what() const
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Name of the file listing the assertion.
@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).
Number of the line listing the assertion.
@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).
Text listing the source code of the asserted condition.
@return Asserted condition source code as specified at construction (or
@c "" if no code was specified).
*/
char const* const code() const;
@@ -151,159 +182,236 @@ private:
};
/**
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}.
Represent the operation where the contract assertion failed.
This is passed as a parameter to the assertion failure handler functions.
For example, it might be necessary to know in which operation an assertion
failed to make sure exceptions are never thrown from destructors, not even
when contract failure handlers are reprogrammed by users to throw exceptions
instead of terminating the program.
do).
@see @RefSect{advanced_topics, Advanced Topics}
*/
enum from {
/** Assertion failed in constructor contract. */
/** Assertion failed when checking constructor contracts. */
from_constructor,
/** Assertion failed in destructor contract. */
/** Assertion failed when checking destructor contracts. */
from_destructor,
/** Assertion failed in function (member or not) contract. */
/** Assertion failed when checking function (member or not) contracts. */
from_function
};
/**
Typef all assertion failure handler functions.
<b>Rationale:</b> Using Boost.Function to handle also lambdas, binds, etc.
@see @RefSect{advanced_topics, Advanced Topics}.
Type of all assertion failure handler functions.
As specified by this type, assertion failure handler functions must be functors
returning @c void and taking a single parameter of type
@RefEnum{boost::contract::from}.
@b Rationale: Using Boost.Function allows to handle any functor (functions but
also lambdas, binds, etc.).
@see @RefSect{advanced_topics, Advanced Topics}
*/
typedef boost::function<void (from)> assertion_failure_handler;
/**
Set the precondition failure handler.
Set a new precondition failure handler and return the old one.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New precondition failure handler functor.
@return Old precondition failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_precondition_failure(assertion_failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW;
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Return the precondition failure handler.
@return Current precondition failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
This is often called only internally by this library.
@b Throws: @c noexcept (or @c throw() if no C++11).
@return 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
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
get_precondition_failure()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Call the precondition hander functor.
This is typically only called internally by this library.
@param where Context of precondition failure.
This is often called only internally by this library.
@b Throws: This can throw in case programmers specify a failure handler that
throws exceptions on precondition failures (not the default).
@param where Operation that failed preconditions (note that destructors
never have preconditions).
*/
void BOOST_CONTRACT_DETAIL_DECLSPEC
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
precondition_failure(from where) /* can throw */;
/**
Set the postcondition failure handler.
Set a new postcondition failure handler and return the old one.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New postcondition failure handler functor.
@return Old postcondition failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_postcondition_failure(assertion_failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW;
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Return the postcondition failure handler.
@return Current postcondition failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
This is often called only internally by this library.
@b Throws: @c noexcept (or @c throw() if no C++11).
@return Postcondition failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}
*/
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
get_postcondition_failure() BOOST_NOEXCEPT_OR_NOTHROW;
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
get_postcondition_failure()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Call the postcondition hander functor.
This is typically only called internally by this library.
@param where Context of postcondition failure.
This is often called only internally by this library.
@b Throws: This can throw in case programmers specify a failure handler that
throws exceptions on postcondition failures (not the default).
@param where Operation that failed postconditions (e.g., this might be useful
to program failure handler functors that never throw from
destructors, not even when they are programmed by users to throw
exceptions instead of terminating the program).
*/
void BOOST_CONTRACT_DETAIL_DECLSPEC
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
postcondition_failure(from where) /* can throw */;
/**
Set the entry invariant failure handler.
Set a new entry invariant failure handler and return the old one.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New entry invariant failure handler functor.
@return Old entry invariant failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_entry_invariant_failure(assertion_failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW;
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Return the entry invariant failure handler.
@return Current entry invariant failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
This is often called only internally by this library.
@b Throws: @c noexcept (or @c throw() if no C++11).
@return 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;
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
get_entry_invariant_failure()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Call the entry invariant hander functor.
This is typically only called internally by this library.
@param where Context of entry invariant failure.
This is often called only internally by this library.
@b Throws: This can throw in case programmers specify a failure handler that
throws exceptions on entry invariant failures (not the default).
@param where Operation that failed entry invariants (e.g., this might be
useful to program failure handler functors that never throw from
destructors, not even when they are programmed by users to throw
exceptions instead of terminating the program).
*/
void BOOST_CONTRACT_DETAIL_DECLSPEC
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
entry_invariant_failure(from where) /* can throw */;
/**
Set the exit invariant failure handler.
Set a new exit invariant failure handler and return the old one.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New exit invariant failure handler functor.
@return Old exit invariant failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
assertion_failure_handler BOOST_CONTRACT_DETAIL_DECLSPEC
assertion_failure_handler
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_exit_invariant_failure(assertion_failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW;
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Return the exit invariant failure handler.
@return Current exit invariant failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
This is often called only internally by this library.
@b Throws: @c noexcept (or @c throw() if no C++11).
@return 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;
/** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
get_exit_invariant_failure()
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
Call the exit invariant hander functor.
This is typically only called internally by this library.
@param where Context of exit invariant failure.
This is often called only internally by this library.
@b Throws: This can throw in case programmers specify a failure handler that
throws exceptions on exit invariant failures (not the default).
@param where Operation that failed exit invariants (e.g., this might be
useful to program failure handler functors that never throw from
destructors, not even when they are programmed by users to throw
exceptions instead of terminating the program).
*/
void BOOST_CONTRACT_DETAIL_DECLSPEC
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
exit_invariant_failure(from where) /* can throw */;
/**
Set the both entry and exit invariant failure handlers at once (for
convenience).
Set both entry and exit invariant failure handlers at once (for convenience).
This is equivalent to calling both
@RefFunc{boost::contract::set_entry_invariant_failure}<c>(f)</c> and
@RefFunc{boost::contract::set_exit_invariant_failure}<c>(f)</c>.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New invariant failure handler functor.
@see @RefSect{advanced_topics, Advanced Topics}.
@see @RefSect{advanced_topics, Advanced Topics}
*/
void BOOST_CONTRACT_DETAIL_DECLSPEC
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_invariant_failure(assertion_failure_handler const& f)
BOOST_NOEXCEPT_OR_NOTHROW;
/** @cond */ OOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
/**
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}.
Set the all contract failure handlers at once (for convenience).
This is equivalent to calling
@RefFunc{boost::contract::set_entry_invariant_failure}<c>(f)</c>,
@RefFunc{boost::contract::set_precondition_failure}<c>(f)</c>,
@RefFunc{boost::contract::set_exit_invariant_failure}<c>(f)</c>, and
@RefFunc{boost::contract::set_postcondition_failure}<c>(f)</c>.
@b Throws: @c noexcept (or @c throw() if no C++11).
@param f New contract 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;
void /** @cond */ BOOST_CONTRACT_DETAIL_DECLSPEC /** @endcond */
set_failure(assertion_failure_handler const& f)
/** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */;
} } // namespace
/** @cond */
#if BOOST_CONTRACT_HEADER_ONLY
#include <boost/contract/detail/inlined/core/exception.hpp>
#endif
/** @endcond */
#endif // #include guard

View File

@@ -1,80 +0,0 @@
#ifndef BOOST_CONTRACT_SET_NOTHING_HPP_
#define BOOST_CONTRACT_SET_NOTHING_HPP_
// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Used to prevent setting other contract conditions after postconditions.
*/
#include <boost/contract/core/config.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
#include <boost/contract/detail/condition/check_base.hpp>
#include <boost/contract/detail/auto_ptr.hpp>
#endif
#include <boost/config.hpp>
namespace boost {
namespace contract {
template<typename RR>
class set_precondition_old_postcondition;
template<typename RR>
class set_old_postcondition;
template<typename RR>
class set_postcondition_only;
}
}
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) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_base check_type;
explicit set_nothing(check_type* check) : check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
template<typename RR>
friend class set_precondition_old_postcondition;
template<typename RR>
friend class set_old_postcondition;
template<typename RR>
friend class set_postcondition_only;
/** @endcond */
};
} } // namespace
#endif // #include guard

View File

@@ -1,140 +0,0 @@
#ifndef BOOST_CONTRACT_SET_OLD_POSTCONDITION_HPP_
#define BOOST_CONTRACT_SET_OLD_POSTCONDITION_HPP_
// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Allow to specify old value assignments and postconditions.
*/
#include <boost/contract/core/set_postcondition_only.hpp>
#include <boost/contract/core/set_nothing.hpp>
#include <boost/contract/core/config.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
#include <boost/contract/detail/condition/check_pre_post.hpp>
#include <boost/contract/detail/auto_ptr.hpp>
#include <boost/contract/detail/none.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS)
#include <boost/contract/detail/debug.hpp>
#endif
#include <boost/config.hpp>
namespace boost {
namespace contract {
template<typename RR>
class set_precondition_old_postcondition;
}
}
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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_old(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_postcondition_only<R>(check_.release());
#else
return set_postcondition_only<R>();
#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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_nothing(check_.release());
#else
return set_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename
boost::contract::detail::none_if_void<R>::type> check_type;
explicit set_old_postcondition(check_type* check) : check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend class set_precondition_old_postcondition<R>;
template<class CC>
friend set_old_postcondition<> constructor(CC* oobj);
template<class CC>
friend set_old_postcondition<> destructor(CC* oobj);
/** @endcond */
};
} } // namespace
#endif // #include guard

View File

@@ -1,110 +0,0 @@
#ifndef BOOST_CONTRACT_SET_POSTCONDITION_ONLY_HPP_
#define BOOST_CONTRACT_SET_POSTCONDITION_ONLY_HPP_
// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Allow to specify postconditions.
*/
#include <boost/contract/core/set_nothing.hpp>
#include <boost/contract/core/config.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
#include <boost/contract/detail/condition/check_pre_post.hpp>
#include <boost/contract/detail/auto_ptr.hpp>
#include <boost/contract/detail/none.hpp>
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
#include <boost/contract/detail/debug.hpp>
#endif
#include <boost/config.hpp>
namespace boost {
namespace contract {
template<typename RR>
class set_precondition_old_postcondition;
template<typename RR>
class set_old_postcondition;
}
}
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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_nothing(check_.release());
#else
return set_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename
boost::contract::detail::none_if_void<R>::type> check_type;
explicit set_postcondition_only(check_type* check) : check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend class set_precondition_old_postcondition<R>;
friend class set_old_postcondition<R>;
/** @endcond */
};
} } // namespace
#endif // #include guard

View File

@@ -1,186 +0,0 @@
#ifndef BOOST_CONTRACT_SET_PRECONDITION_OLD_POSTCONDITION_HPP_
#define BOOST_CONTRACT_SET_PRECONDITION_OLD_POSTCONDITION_HPP_
// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Allow to specify preconditions, old value assignments, and postconditions.
*/
#include <boost/contract/core/set_old_postcondition.hpp>
#include <boost/contract/core/set_postcondition_only.hpp>
#include <boost/contract/core/set_nothing.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/decl.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
#include <boost/contract/detail/condition/check_pre_post.hpp>
#include <boost/contract/detail/auto_ptr.hpp>
#include <boost/contract/detail/none.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS)
#include <boost/contract/detail/debug.hpp>
#endif
#include <boost/config.hpp>
namespace boost {
namespace contract {
class virtual_;
}
}
namespace boost { namespace contract {
/**
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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_pre(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_old_postcondition<R>(check_.release());
#else
return set_old_postcondition<R>();
#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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_old(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_postcondition_only<R>(check_.release());
#else
return set_postcondition_only<R>();
#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
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_nothing(check_.release());
#else
return set_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename
boost::contract::detail::none_if_void<R>::type> check_type;
explicit set_precondition_old_postcondition(check_type* check) :
check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend set_precondition_old_postcondition<> function();
template<class CC>
friend set_precondition_old_postcondition<> public_function();
template<class CC>
friend set_precondition_old_postcondition<> public_function(CC* oobj);
template<class CC>
friend set_precondition_old_postcondition<> public_function(
virtual_* vv, CC* oobj);
template<typename RR, class CC>
friend set_precondition_old_postcondition<RR> public_function(
virtual_* vv, RR& rr, CC* oobj);
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs)
/** @endcond */
};
} } // namespace
#endif // #include guard

View File

@@ -0,0 +1,456 @@
#ifndef BOOST_CONTRACT_SPECIFY_HPP_
#define BOOST_CONTRACT_SPECIFY_HPP_
// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Facilities to specify preconditions, old value assignments, and postconditions.
*/
#include <boost/contract/core/config.hpp>
#include <boost/contract/detail/decl.hpp>
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
#include <boost/contract/detail/condition/check_base.hpp>
#include <boost/contract/detail/condition/check_pre_post.hpp>
#include <boost/contract/detail/auto_ptr.hpp>
#include <boost/contract/detail/none.hpp>
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS)
#include <boost/contract/detail/debug.hpp>
#endif
#include <boost/config.hpp>
namespace boost {
namespace contract {
class virtual_;
template<typename VR>
class specify_precondition_old_postcondition;
template<typename VR>
class specify_old_postcondition;
template<typename VR>
class specify_postcondition_only;
}
}
namespace boost { namespace contract {
/**
Used to prevent setting other contract conditions after postconditions.
This class has no member function so it is used to prevent specifying contract
functors.
@see @RefSect{tutorial, Tutorial}
*/
class specify_nothing { // Copyable (as *).
public:
/**
Destruct this object.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
*/
~specify_nothing() BOOST_NOEXCEPT_IF(false) {}
// No set member functions here.
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_base check_type;
explicit specify_nothing(check_type* check) : check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
template<typename VR>
friend class specify_precondition_old_postcondition;
template<typename VR>
friend class specify_old_postcondition;
template<typename VR>
friend class specify_postcondition_only;
/** @endcond */
};
/**
Allow to specify postconditions.
Allow to program functors this library will call to check postconditions.
@see @RefSect{tutorial, Tutorial}
@tparam VirtualResult Return type of the contracted function if that is either
a virtual or an overriding public function, otherwise
this is always @c void.
*/
template<typename VirtualResult = void>
class specify_postcondition_only { // Copyable (as *).
public:
/**
Destruct this object.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
*/
~specify_postcondition_only() BOOST_NOEXCEPT_IF(false) {}
/**
Allow to specify postconditions.
@param f Functor called by this library to check postconditions @c f().
Postcondition assertions within this functor call are usually
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any
exception thrown by a call to this functor indicates a
postcondition failure (and will result in this library calling
@RefFunc{boost::contract::postcondition_failure}). This
functor must be a nullary functor if @c VirtualResult is
@c void, otherwise it must be a unary functor taking the return
value as a parameter of type <c>VirtualResult const&</c> (to
avoid extra copies, or @c VirtualResult and also
<c>VirtualResult const</c> if extra copies of the return value
are irrelevant). This functor should capture variables by
(constant) references (to access the values they will have at
function exit).
@return After postconditions have been specified, return object that does
not allow to specify any additional contract.
*/
template<typename F>
specify_nothing postcondition(F const& f) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_nothing(check_.release());
#else
return specify_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename boost::contract
::detail::none_if_void<VirtualResult>::type> check_type;
explicit specify_postcondition_only(check_type* check) :
check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend class specify_precondition_old_postcondition<VirtualResult>;
friend class specify_old_postcondition<VirtualResult>;
/** @endcond */
};
/**
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.
@see @RefSect{tutorial, Tutorial}
@tparam VirtualResult Return type of the contracted function if that is either
a virtual or an overriding public function, otherwise
this is always @c void.
*/
template<typename VirtualResult = void>
class specify_old_postcondition { // Copyable (as *).
public:
/**
Destruct this object.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
*/
~specify_old_postcondition() BOOST_NOEXCEPT_IF(false) {}
/**
Allow to specify old value assignments to execute just before the function
body.
In most cases, it should be sufficient to initialize old value pointers as
soon as they are declared so it should not be necessary to use this function
(see @RefSect{advanced_topics, Advanced Topics}).
@param f Functor called by this library to assign old values @c f(). This
functor is called just before the function body is executed, but
after precondition and class invariants are checked (when they
are specified). Old value pointers within this functor call are
usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. Any
exception thrown by a call to this functor is handled as a
postcondition failure (and will result in this library calling
@RefFunc{boost::contract::postcondition_failure} because old
values are ultimately used to assert postconditions). This
functor must be a nullary functor. This functor should capture
old value pointers by references so they can be assigned (all
other variables needed to evaluate old value expressions can be
captured by (constant) value, or better by (constant) reference
to avoid extra copies).
@return After old value assignments have been specified, return object that
allows to optionally specify postconditions.
*/
template<typename F>
specify_postcondition_only<VirtualResult> old(F const& f) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_old(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_postcondition_only<VirtualResult>(check_.release());
#else
return specify_postcondition_only<VirtualResult>();
#endif
}
/**
Allow to specify postconditions.
@param f Functor called by this library to check postconditions @c f().
Postcondition assertions within this functor call are usually
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any
exception thrown by a call to this functor indicates a
postcondition failure (and will result in this library calling
@RefFunc{boost::contract::postcondition_failure}). This
functor must be a nullary functor if @c VirtualResult is
@c void, otherwise it must be a unary functor taking the return
value as a parameter of type <c>VirtualResult const&</c> (to
avoid extra copies, or @c VirtualResult and also
<c>VirtualResult const</c> if extra copies of the return value
are irrelevant). This functor should capture variables by
(constant) references (to access the values they will have at
function exit).
@return After postconditions have been specified, return object that does
not allow to specify any additional contract.
*/
template<typename F>
specify_nothing postcondition(F const& f) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_nothing(check_.release());
#else
return specify_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename boost::contract
::detail::none_if_void<VirtualResult>::type> check_type;
explicit specify_old_postcondition(check_type* check) :
check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend class specify_precondition_old_postcondition<VirtualResult>;
template<class C>
friend specify_old_postcondition<> constructor(C*);
template<class C>
friend specify_old_postcondition<> destructor(C*);
/** @endcond */
};
/**
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.
@see @RefSect{tutorial, Tutorial}
@tparam VirtualResult Return type of the contracted function if that is either
a virtual or an overriding public function, otherwise
this is always @c void.
*/
template<
typename VirtualResult /* = void (already in fwd decl from decl.hpp) */
#ifdef DOXYGEN
= void
#endif
>
class specify_precondition_old_postcondition { // Copyable (as *).
public:
/**
Destruct this object.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
*/
~specify_precondition_old_postcondition() BOOST_NOEXCEPT_IF(false) {}
/**
Allow to specify preconditions.
@param f Functor called by this library to check preconditions @c f().
Precondition assertions within this functor call are usually
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any
exception thrown by a call to this functor indicates a
precondition failure (and will result in this library calling
@RefFunc{boost::contract::precondition_failure}). This functor
must be a nullary functor. This functor can capture variables by
(constant) 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>
specify_old_postcondition<VirtualResult> precondition(F const& f) {
#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_pre(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_old_postcondition<VirtualResult>(check_.release());
#else
return specify_old_postcondition<VirtualResult>();
#endif
}
/**
Allow to specify old value assignments to execute just before the function
body.
In most cases, it should be sufficient to initialize old value pointers as
soon as they are declared so it should not be necessary to use this function
(see @RefSect{advanced_topics, Advanced Topics}).
@param f Functor called by this library to assign old values @c f(). This
functor is called just before the function body is executed, but
after precondition and class invariants are checked (when they
are specified). Old value pointers within this functor call are
usually assigned using @RefMacro{BOOST_CONTRACT_OLDOF}. Any
exception thrown by a call to this functor is handled as a
postcondition failure (and will result in this library calling
@RefFunc{boost::contract::postcondition_failure} because old
values are ultimately used to assert postconditions). This
functor must be a nullary functor. This functor should capture
old value pointers by references so they can be assigned (all
other variables needed to evaluate old value expressions can be
captured by (constant) value, or better by (constant) reference
to avoid extra copies).
@return After old value assignments have been specified, return object that
allows to optionally specify postconditions.
*/
template<typename F>
specify_postcondition_only<VirtualResult> old(F const& f) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_old(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_postcondition_only<VirtualResult>(check_.release());
#else
return specify_postcondition_only<VirtualResult>();
#endif
}
/**
Allow to specify postconditions.
@param f Functor called by this library to check postconditions @c f().
Postcondition assertions within this functor call are usually
programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any
exception thrown by a call to this functor indicates a
postcondition failure (and will result in this library calling
@RefFunc{boost::contract::postcondition_failure}). This
functor must be a nullary functor if @c VirtualResult is
@c void, otherwise it must be a unary functor taking the return
value as a parameter of type <c>VirtualResult const&</c> (to
avoid extra copies, or @c VirtualResult and also
<c>VirtualResult const</c> if extra copies of the return value
are irrelevant). This functor should capture variables by
(constant) references (to access the values they will have at
function exit).
@return After postconditions have been specified, return object that does
not allow to specify any additional contract.
*/
template<typename F>
specify_nothing postcondition(F const& f) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
BOOST_CONTRACT_DETAIL_DEBUG(check_);
check_->set_post(f);
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return specify_nothing(check_.release());
#else
return specify_nothing();
#endif
}
/** @cond */
private:
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
typedef boost::contract::detail::check_pre_post<typename boost::contract
::detail::none_if_void<VirtualResult>::type> check_type;
explicit specify_precondition_old_postcondition(check_type* check) :
check_(check) {}
boost::contract::detail::auto_ptr<check_type> check_;
#endif
// Friends (used to limit library's public API).
friend class guard;
friend specify_precondition_old_postcondition<> function();
template<class C>
friend specify_precondition_old_postcondition<> public_function();
template<class C>
friend specify_precondition_old_postcondition<> public_function(C*);
template<class C>
friend specify_precondition_old_postcondition<> public_function(
virtual_*, C*);
template<typename VR, class C>
friend specify_precondition_old_postcondition<VR> public_function(
virtual_*, VR&, C*);
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
O, VR, F, C, Args, v, r, f, obj, args)
/** @endcond */
};
} } // namespace
#endif // #include guard

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Used to contract virtual public functions.
Facility to declare virtual public functions with contracts.
*/
#include <boost/contract/core/config.hpp>
@@ -33,16 +33,27 @@ 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.)
Class to mark declarations of virtual public functions.
Virtual public functions (and therefore 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 have
default value @c 0 (i.e., null). (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}.
This extra parameter does not alter the calling interface of the contracted
function because it is always the last parameter and it has a default value (so
it is always omitted when users call the contracted function). This extra
parameter must be passed to @RefFunc{boost::contract::public_function},
@RefMacro{BOOST_CONTRACT_OLDOF}, and all other operations of this library that
require a pointer to @RefClass{boost::contract::virtual_}. A part from that,
this class is not intended to be directly used by programmers (and that is why
this class does not have any public member and it is not copyable).
@b Rationale: This extra parameter is internally used by this library to
recognize virtual public functions to implement subcontracting
(@c virtual cannot be introspected using template
meta-programming techniques in C++).
@see @RefSect{tutorial, Tutorial}
*/
class virtual_ : private boost::noncopyable { // Avoid copy queue, stack, etc.
/** @cond */
@@ -101,7 +112,7 @@ class virtual_ : private boost::noncopyable { // Avoid copy queue, stack, etc.
std::queue<boost::shared_ptr<void> > old_inits_;
std::stack<boost::shared_ptr<void> > old_copies_;
boost::any result_ptr_;
boost::any result_ptr_; // Result for virtual and overriding functions.
char const* result_type_name_;
bool result_optional_;
#endif

View File

@@ -21,24 +21,28 @@ 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).
This is used to specify postconditions, old value assignments at body, and check
class invariants for destructors (destructors cannot not have preconditions, see
@RefSect{contract_programming_overview, Contract Programming Overview}).
For optimization, this can be omitted for destructors that do not have
postconditions when the enclosing class has no invariants.
@see @RefSect{tutorial, Tutorial}
@param obj The object @c this from the scope of the contracted destructor.
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the body
of the contracted destructor (otherwise this library will generate a
run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class C>
set_old_postcondition<> destructor(C* obj) {
// Must #if also on ..._PRECONDITIONS here because set_... is generic.
template<class Class>
specify_old_postcondition<> destructor(Class* obj) {
// Must #if also on ..._PRECONDITIONS here because specify_... is generic.
#if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
!defined(BOOST_CONTRACT_NO_PRECONDITIONS)
return set_old_postcondition<>(
new boost::contract::detail::destructor<C>(obj));
return specify_old_postcondition<>(
new boost::contract::detail::destructor<Class>(obj));
#else
return set_old_postcondition<>();
return specify_old_postcondition<>();
#endif
}

View File

@@ -22,10 +22,7 @@
#include <boost/contract/core/access.hpp>
#include <boost/contract/core/config.hpp>
#include <boost/contract/core/exception.hpp>
#include <boost/contract/core/set_nothing.hpp>
#include <boost/contract/core/set_old_postcondition.hpp>
#include <boost/contract/core/set_postcondition_only.hpp>
#include <boost/contract/core/set_precondition_old_postcondition.hpp>
#include <boost/contract/core/specify.hpp>
#include <boost/contract/core/virtual.hpp>
#endif // #include guard

View File

@@ -34,9 +34,11 @@ private:
} } } // namespace
/** @cond Needed because this header included by other public headers. */
#if BOOST_CONTRACT_HEADER_ONLY
#include <boost/contract/detail/inlined/detail/check_guard.hpp>
#endif
/** @endcond */
#endif // #include guard

View File

@@ -41,18 +41,18 @@
namespace boost { namespace contract { namespace detail {
template<typename R>
template<typename VR>
class check_pre_post : public check_base { // Non-copyable base.
public:
explicit check_pre_post(boost::contract::from from) : check_base(from) {}
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
private:
typedef typename boost::mpl::if_<is_optional<R>,
typedef typename boost::mpl::if_<is_optional<VR>,
boost::optional<typename boost::remove_reference<typename
optional_value_type<R>::type>::type const&> const&
optional_value_type<VR>::type>::type const&> const&
,
R const&
VR const&
>::type r_type;
BOOST_CONTRACT_DETAIL_CHECK_PRE_POST_DEF_(

View File

@@ -31,8 +31,8 @@
namespace boost { namespace contract { namespace detail {
template<typename R, class C>
class check_pre_post_inv : public check_pre_post<R> { // Non-copyable base.
template<typename VR, class C>
class check_pre_post_inv : public check_pre_post<VR> { // Non-copyable base.
#if !defined(BOOST_CONTRACT_NO_INVARIANTS) && \
!defined(BOOST_CONTRACT_PERMISSIVE)
BOOST_STATIC_ASSERT_MSG(
@@ -95,7 +95,7 @@ class check_pre_post_inv : public check_pre_post<R> { // Non-copyable base.
public:
// obj can be 0 for static member functions.
explicit check_pre_post_inv(boost::contract::from from, C* obj) :
check_pre_post<R>(from)
check_pre_post<VR>(from)
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)

View File

@@ -67,10 +67,10 @@ namespace check_subcontracted_pre_post_inv_ {
class signal_not_checked {};
}
// O, R, F, and Args-i can be none types (but C cannot).
// O, VR, F, and Args-i can be none types (but C cannot).
BOOST_CONTRACT_DETAIL_DECL_DETAIL_CHECK_SUBCONTRACTED_PRE_POST_INV_Z(1,
/* is_friend = */ 0, O, R, F, C, Args) : // Non-copyable base.
public check_pre_post_inv<R, C>
/* is_friend = */ 0, O, VR, F, C, Args) : // Non-copyable base.
public check_pre_post_inv<VR, C>
{
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
@@ -145,12 +145,12 @@ public:
boost::contract::from from,
boost::contract::virtual_* v,
C* obj,
R& r
VR& r
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args, &, args)
) :
check_pre_post_inv<R, C>(from, obj)
check_pre_post_inv<VR, C>(from, obj)
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
, r_(r)
#endif
@@ -176,8 +176,8 @@ public:
boost::contract::virtual_::no_action);
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
v_->result_ptr_ = &r_;
v_->result_type_name_ = typeid(R).name();
v_->result_optional_ = is_optional<R>::value;
v_->result_type_name_ = typeid(VR).name();
v_->result_optional_ = is_optional<VR>::value;
#endif
} else v_ = 0;
}
@@ -275,7 +275,7 @@ private:
}
typedef typename boost::remove_reference<typename
optional_value_type<R>::type>::type r_type;
optional_value_type<VR>::type>::type r_type;
boost::optional<r_type const&> r; // No result copy in this code.
if(!base_call_) r = r_;
else if(v_->result_optional_) {
@@ -307,7 +307,7 @@ private:
}
}
}
check_post_r<R>(r);
check_post_r<VR>(r);
}
template<typename R_, typename Result>
@@ -450,7 +450,7 @@ private:
#endif
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
R& r_;
VR& r_;
#endif
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
!defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \

View File

@@ -23,26 +23,26 @@
#define BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
arity, is_friend, has_result, \
O, R, F, C, Args, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
template< \
class O \
BOOST_PP_COMMA_IF(has_result) \
BOOST_PP_EXPR_IIF(has_result, typename R) \
BOOST_PP_EXPR_IIF(has_result, typename VR) \
, typename F \
, class C \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, Args) \
> \
BOOST_PP_EXPR_IIF(is_friend, friend) \
boost::contract::set_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, R)> \
boost::contract::specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, VR)> \
/* no boost::contract:: here for friends (otherwise need fwd decl) */ \
public_function( \
boost::contract::virtual_* v \
BOOST_PP_COMMA_IF(has_result) \
BOOST_PP_EXPR_IIF(has_result, R& r) \
BOOST_PP_EXPR_IIF(has_result, VR& r) \
, F f \
, C* obj \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
@@ -51,16 +51,16 @@
#if BOOST_CONTRACT_DETAIL_TVARIADIC
#define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
O, R, F, C, Args, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
~, /* is_friend = */ 1, /* has_result = */ 0, \
O, R, F, C, Args, v, r, f, obj, args \
O, VR, F, C, Args, v, r, f, obj, args \
); \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
~, /* is_friend = */ 1, /* has_result = */ 1, \
O, R, F, C, Args, v, r, f, obj, args \
O, VR, F, C, Args, v, r, f, obj, args \
);
#else
/* PRIVATE */
@@ -84,25 +84,25 @@
/* PUBLIC */
#define BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(z, \
O, R, F, C, Args, \
O, VR, F, C, Args, \
v, r, f, obj, args \
) \
BOOST_PP_REPEAT_ ## z( \
BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
(/* has_result = */ 0, O, R, F, C, Args, v, r, f, obj, args) \
(/* has_result = */ 0, O, VR, F, C, Args, v, r, f, obj, args) \
) \
BOOST_PP_REPEAT_ ## z( \
BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTION_, \
(/* has_result = */ 1, O, R, F, C, Args, v, r, f, obj, args) \
(/* has_result = */ 1, O, VR, F, C, Args, v, r, f, obj, args) \
)
#endif
#define BOOST_CONTRACT_DETAIL_DECL_DETAIL_CHECK_SUBCONTRACTED_PRE_POST_INV_Z( \
z, is_friend, O, R, F, C, Args) \
z, is_friend, O, VR, F, C, Args) \
template< \
class O, typename R, typename F, class C \
class O, typename VR, typename F, class C \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS) \
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, \
BOOST_CONTRACT_MAX_ARGS, Args) \
@@ -120,8 +120,8 @@ namespace boost {
namespace contract {
class virtual_;
template<typename R = void>
class set_precondition_old_postcondition;
template<typename VR = void>
class specify_precondition_old_postcondition;
}
}

View File

@@ -26,9 +26,9 @@ namespace boost { namespace contract { namespace detail {
// Ctor subcontracting impl via C++ obj construction mechanism.
template<class C>
class constructor :
public check_pre_post_inv</* R = */ none, C> { // Non-copyable base.
public check_pre_post_inv</* VR = */ none, C> { // Non-copyable base.
public:
explicit constructor(C* obj) : check_pre_post_inv</* R = */ none, C>(
explicit constructor(C* obj) : check_pre_post_inv</* VR = */ none, C>(
boost::contract::from_constructor, obj) {}
private:

View File

@@ -26,9 +26,9 @@ namespace boost { namespace contract { namespace detail {
// Dtor subcontracting impl via C++ obj destruction mechanism.
template<class C>
class destructor :
public check_pre_post_inv</* R = */ none, C> { // Non-copyable base.
public check_pre_post_inv</* VR = */ none, C> { // Non-copyable base.
public:
explicit destructor(C* obj) : check_pre_post_inv</* R = */ none, C>(
explicit destructor(C* obj) : check_pre_post_inv</* VR = */ none, C>(
boost::contract::from_destructor, obj) {}
private:

View File

@@ -23,9 +23,9 @@ namespace boost { namespace contract { namespace detail {
// Used for free function, private and protected member functions.
class function :
public check_pre_post</* R = */ none> { // Non-copyable base.
public check_pre_post</* VR = */ none> { // Non-copyable base.
public:
explicit function() : check_pre_post</* R = */ none>(
explicit function() : check_pre_post</* VR = */ none>(
boost::contract::from_function) {}
private:

View File

@@ -29,26 +29,26 @@
namespace boost { namespace contract { namespace detail {
template<
class O, typename R, typename F, class C
class O, typename VR, typename F, class C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
>
class public_function : // Non-copyable base.
public check_subcontracted_pre_post_inv<
O, R, F, C
O, VR, F, C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
>
{
public:
explicit public_function(
boost::contract::virtual_* v, C* obj, R& r
boost::contract::virtual_* v, C* obj, VR& r
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args, &, args)
) :
check_subcontracted_pre_post_inv<
O, R, F, C
O, VR, F, C
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
BOOST_CONTRACT_MAX_ARGS, Args)

View File

@@ -29,10 +29,10 @@ namespace boost { namespace contract { namespace detail {
// No subcontracting because static so no obj and no substitution principle.
template<class C>
class public_static_function :
public check_pre_post_inv</* R = */ none, C> { // Non-copyable base.
public check_pre_post_inv</* VR = */ none, C> { // Non-copyable base.
public:
explicit public_static_function() :
check_pre_post_inv</* R = */ none, C>(boost::contract::from_function,
check_pre_post_inv</* VR = */ none, C>(boost::contract::from_function,
/* obj = */ 0)
{}

View File

@@ -21,41 +21,27 @@ namespace boost { namespace contract {
/**
Program contracts for non-member, private and protected functions.
This is used to specify preconditions, postconditions, and old value assignments
at body for non-member, private and protected functions (these functions never
check class invariants, see
@RefSect{contract_programming_overview, Contract Programming Overview}).
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
For optimization, this can be omitted 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}
@see @RefSect{tutorial, Tutorial}
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the body
of the contracted function (otherwise this library will generate a
run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
set_precondition_old_postcondition<> function() {
// Must #if also on ..._INVARIANTS here because set_... is generic.
specify_precondition_old_postcondition<> function() {
// Must #if also on ..._INVARIANTS here because specify_... is generic.
#if !defined(BOOST_CONTRACT_NO_FUNCTIONS) || \
!defined(BOOST_CONTRACT_NO_INVARIANTS)
return set_precondition_old_postcondition<>(
return specify_precondition_old_postcondition<>(
new boost::contract::detail::function());
#else
return set_precondition_old_postcondition<>();
return specify_precondition_old_postcondition<>();
#endif
}

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
RAII object that checks the contracts.
RAII object to check contracts.
*/
#include <boost/contract/detail/all_core_headers.hpp>
@@ -43,20 +43,22 @@ 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}.
values when it is constructed. Then it checks exit invariants and postconditions
when it is destructed. In addition, this object markes sure that postconditions
are checked only if the body does not throw an exception, constructors never
check entry invariants, destructors check exit invariants only if their bodies
throw an exception, static invariants are always checked at entry and exit, 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).
class guard { // Copy ctor only (as move via ptr release).
public:
/**
Construct this object copying it from specified one.
Construct this object copying it from the 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).
contract checking ownership is transfered from the copied object to this
object).
*/
guard(guard const& other) // Copy ctor moves check_ pointer to dest.
#if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
@@ -67,101 +69,112 @@ public:
{}
/**
Construct this object from specified contract.
Check entry invariants (as they apply for specified contract).
Implicit so initialization operator @c = can be used.
Construct this object from the specified contract.
Check entry invariants (if they apply to the specified contract).
This constructor is not @c explicit so initializations can use operator @c =
syntax.
<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.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
@param contract Contract to be checked.
@tparam VirtualResult Return type of the contracted function if that is
either a virtual or an overriding public function,
otherwise this is always @c void.
*/
template<typename R>
/* implicit */ guard(set_precondition_old_postcondition<R> const& contract)
template<typename VirtualResult>
/* implicit */ guard(specify_precondition_old_postcondition<VirtualResult>
const& contract)
#ifndef DOXYGEN
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_precondition_old_postcondition<R>)
BOOST_CONTRACT_GUARD_CTOR_DEF_(
specify_precondition_old_postcondition<VirtualResult>)
#else
;
#endif
/**
Construct this object from specified contract.
Check entry invariants (as they apply for specified contract) and check
Construct this object from the specified contract.
Check entry invariants (if they apply to the specified contract) and check
preconditions.
Implicit so initialization operator @c = can be used.
This constructor is not @c explicit so initializations can use operator @c =
syntax.
<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.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
@param contract Contract to be checked.
@tparam VirtualResult Return type of the contracted function if that is
either a virtual or an overriding public function,
otherwise this is always @c void.
*/
template<typename R>
/* implicit */ guard(set_old_postcondition<R> const& contract)
template<typename VirtualResult>
/* implicit */ guard(specify_old_postcondition<VirtualResult> const&
contract)
#ifndef DOXYGEN
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_old_postcondition<R>)
BOOST_CONTRACT_GUARD_CTOR_DEF_(specify_old_postcondition<VirtualResult>)
#else
;
#endif
/**
Construct this object from specified contract.
Check entry invariants (as they apply for specified contract), check
Construct this object from the specified contract.
Check entry invariants (if they apply to the specified contract) and check
preconditions, and assign old values.
Implicit so initialization operator @c = can be used.
This constructor is not @c explicit so initializations can use operator @c =
syntax.
<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.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
@param contract Contract to be checked.
@tparam VirtualResult Return type of the contracted function if that is
either a virtual or an overriding public function,
otherwise this is always @c void.
*/
template<typename R>
/* implicit */ guard(set_postcondition_only<R> const& contract)
template<typename VirtualResult>
/* implicit */ guard(specify_postcondition_only<VirtualResult> const&
contract)
#ifndef DOXYGEN
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_postcondition_only<R>)
BOOST_CONTRACT_GUARD_CTOR_DEF_(
specify_postcondition_only<VirtualResult>)
#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.
Construct this object from the specified contract.
Check entry invariants (if they apply to the specified contract) and check
preconditions, and assign old values (plus the destructor of this object
will also check postconditions in this case).
This constructor is not @c explicit so initializations can use operator @c =
syntax.
<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.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_precondition_failure}, etc.).
@param contract Contract to be checked.
*/
/* implicit */ guard(set_nothing const& contract)
/* implicit */ guard(specify_nothing const& contract)
#ifndef DOXYGEN
BOOST_CONTRACT_GUARD_CTOR_DEF_(set_nothing)
BOOST_CONTRACT_GUARD_CTOR_DEF_(specify_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).
Destruct this object.
Check exit invariants (if they apply to the contract specified at
construction) and postconditions (if the body did not throw and
postconditions apply to the contract specified at construction).
<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.
@b Throws: This can throw (i.e., @c noexcept(false)) in case programmers
specify failure handlers that throw exceptions instead of
terminating the program (see
@RefFunc{boost::contract::set_postcondition_failure}, etc.).
*/
~guard() BOOST_NOEXCEPT_IF(false) {} // Allow auto_ptr dtor to throw.

View File

@@ -8,7 +8,7 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Facilities for old values.
Facilities to support old values.
*/
#include <boost/contract/detail/all_core_headers.hpp>
@@ -66,21 +66,23 @@ BOOST_CONTRACT_ERROR_macro_OLDOF_requires_variadic_macros_otherwise_manually_pro
// 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
Macro typically used to copy an old value expression and assign it to an old
value pointer.
The expression expanded by this macro should be assigned to an old value
pointer of type @RefClass{boost::contract::old_ptr} or
@RefClass{boost::contract::old_ptr_noncopyable}.
This is a variadic macro. On compilers that do not support variadic macros,
programmers can manually copy old value expressions without using this macro
(see @RefSect{advanced_topics, Advanced Topics}).
@see @RefSect{tutorial, Tutorial}
@param ... This macro usually takes a single parameter as the old value
expression to be copied. However, for virtual and 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}.
the pointer to @RefClass{boost::contract::virtual_} and the second
parameter is the old value expression to be copied.
*/
#define BOOST_CONTRACT_OLDOF(...) \
BOOST_PP_CAT( /* CAT(..., EMTPY()) required on MSVC */ \
@@ -98,12 +100,12 @@ also @RefSect{advanced_topics, Advanced Topics}).
/** @cond */
namespace boost {
namespace contract {
class unconvertible_old;
class old_value;
}
// Needed because `unconvertible_old` incomplete type when trait used.
// Needed because `old_value` incomplete type when trait used.
template<>
struct is_copy_constructible<contract::unconvertible_old> : true_type {};
struct is_copy_constructible<contract::old_value> : true_type {};
}
/** @endcond */
@@ -113,11 +115,15 @@ 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.
Old value pointer (that requires the pointed old value type to be copy
constructible).
This is set to point to an actual old value via either
@RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old} (that is
why this class does not have public non-default constructors).
@see @RefSect{tutorial, Tutorial}
@tparam T Type of the pointed old value. This type must be copy constructible,
otherwise this pointer will always be null and this library will
generate a compile-time error if this pointer is dereferenced.
*/
template<typename T>
class old_ptr { /* copyable (as *) */
@@ -131,10 +137,10 @@ public:
/**
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.
compile-time error if the pointed type @c T is not copy constructible.
@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).
the program so this member function is @c const and it returns the
old value as a constant reference).
*/
T const& operator*() const {
BOOST_STATIC_ASSERT_MSG(
@@ -146,13 +152,14 @@ public:
}
/**
Access the pointed old value.
This will generate a compile-time error if the pointed type is not copyable.
Structure-dereference this old value pointer.
This will generate a compile-time error if the pointed type @c T is not
copy constructible.
@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).
the program so this member function is @c const and it returns the
old value as a constant pointer to a constant object).
*/
T const* operator->() const {
T const* const operator->() const {
BOOST_STATIC_ASSERT_MSG(
boost::is_copy_constructible<T>::value,
"old_ptr<T> requires T copy constructor, otherwise use old_ptr_noncopyable<T>"
@@ -164,7 +171,7 @@ public:
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr<T>, !!ptr_)
#else
/**
Safe-bool operator.
Check if this old value pointer is null or not (safe-bool operator).
@return True if this pointer is not null, false otherwise.
*/
explicit operator bool() const;
@@ -179,17 +186,20 @@ private:
boost::shared_ptr<T const> ptr_;
friend class convertible_old;
friend class old_pointer;
friend class old_ptr_noncopyable<T>;
/** @endcond */
};
/**
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).
Old value pointer (that does not require the pointed old value type to be copy
constructible).
This is set to point to an actual old value via either
@RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old}.
@see @RefSect{advanced_topics, Advanced Topics}
@tparam T Type of pointed old value. If this type is not copy constructible,
this pointer will always be null (but this library will not generate
compile-time errors when this pointer is dereferenced).
*/
template<typename T>
class old_ptr_noncopyable { /* copyable (as *) */
@@ -201,23 +211,21 @@ public:
old_ptr_noncopyable() {}
/**
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}.
Construct this object from an old value pointer of copyable-only types.
This constructor is implicitly called by this library when assigning an
object of this type using @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).
/**
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).
compile-time error if the pointed type @c T is not copy constructible).
@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).
the program so this member function is @c const and it returns the
old vale as a constant reference).
*/
T const& operator*() const {
BOOST_CONTRACT_DETAIL_DEBUG(ptr_);
@@ -225,14 +233,14 @@ public:
}
/**
Access the pointed old value.
(This will not generate a compile-time error if the pointed type is not
copyable.)
Structure-dereference this old value pointer.
(This will not generate a compile-time error if the pointed type @c T is not
copy constructible.)
@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).
the program so this member function is @c const and it returns the
old value as a constant pointer to a constant object).
*/
T const* operator->() const {
T const* const operator->() const {
return ptr_.operator->();
}
@@ -240,7 +248,7 @@ public:
BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_noncopyable<T>, !!ptr_)
#else
/**
Safe-bool operator.
Check if this old value pointer is null or not (safe-bool operator).
@return True if this pointer is not null, false otherwise.
*/
explicit operator bool() const;
@@ -255,76 +263,89 @@ private:
boost::shared_ptr<T const> ptr_;
friend class convertible_old;
friend class old_pointer;
/** @endcond */
};
/**
Internally hold old value copies.
@see @RefSect{advanced_topics, Advanced Topics}.
Convert user expressions in old values.
This class is often only implicitly used by this library and it does not
explicitly appear in user code.
On older compilers that cannot correctly deduce the
@c boost::is_copy_constructible trait, programmers can manually specialize that
trait to make sure that only old value types that are copy constructible are
actually copied (see the @c boost::is_copy_constructible documentation).
@see @RefSect{advanced_topics, Advanced Topics}
*/
class unconvertible_old { // Copyable (as *).
class old_value { // 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}).
Construct this object from the specified old value when the old value type
is copy constructible.
The specified old value is copied (one time only) and the related old value
pointer will be set to not null (no copy is made instead if postconditions
are not being checked, see @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}).
@tparam T Old value type.
@param old_value Old value to be copied.
@param old Old value to be copied.
*/
template<typename T>
/* implicit */ unconvertible_old(
T const& old_value,
/* implicit */ old_value(
T const& old,
typename boost::enable_if<boost::is_copy_constructible<T> >::type* = 0
)
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
: ptr_(boost::make_shared<T>(old_value)) // The one single T's copy.
: ptr_(boost::make_shared<T>(old)) // The one single T's copy.
#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.
Construct this object from the specified old value when the old value type
is not copy constructible.
The specified old value cannot be copied in this case so it is not copied
and the related old value pointer will always be null.
@tparam T Old value type.
@param old_value Old value (that will not be copied in this case).
@param old Old value (that will not be copied in this case).
*/
template<typename T>
/* implicit */ unconvertible_old(
T const& old_value,
/* implicit */ old_value(
T const& old,
typename boost::disable_if<boost::is_copy_constructible<T> >::type* = 0
) {} // Leave ptr_ null (and no copy of T).
/** @cond */
private:
explicit unconvertible_old() {}
explicit old_value() {}
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
boost::shared_ptr<void> ptr_;
#endif
friend class convertible_old;
friend class old_pointer;
friend unconvertible_old null_old();
friend old_value null_old();
/** @endcond */
};
/**
Internally convert old value copies to old value pointers.
@see @RefSect{advanced_topics, Advanced Topics}.
Convert old value copies to old value pointers.
This class is often used only implicitly by this library and it does not
explicitly appear in user code (that is why this class does not have public
constructors, etc.).
@see @RefSect{advanced_topics, Advanced Topics}
*/
class convertible_old { // Copyable (as *).
class old_pointer { // Copyable (as *).
public:
/**
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).
Convert this object to an old value pointer (the old value type might or not
be copy constructible).
For example, this is implicitly called when assigning or initializing old
value pointers.
@tparam T Type of the pointed old value. The old value pointer will always
be null if this type is not copy constructible (but this library
will not generate a compile-time error).
*/
template<typename T>
/* implicit */ operator old_ptr_noncopyable<T>() {
@@ -332,10 +353,13 @@ public:
}
/**
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).
Convert this object to an old value pointer (the old value type must be
copy constructible).
For example, this is implicitly called when assigning or initializing old
value pointers.
@tparam T Type of the pointed old value. This type must be copy
constructible, otherwise this library will generate a compile-time
error if the old value pointer is dereferenced.
*/
template<typename T>
/* implicit */ operator old_ptr<T>() {
@@ -344,7 +368,7 @@ public:
/** @cond */
private:
explicit convertible_old(virtual_* v, unconvertible_old const& old)
explicit old_pointer(virtual_* v, old_value const& old)
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
: v_(v), ptr_(old.ptr_)
#endif
@@ -408,45 +432,62 @@ private:
boost::shared_ptr<void> ptr_;
#endif
friend convertible_old make_old(unconvertible_old const&);
friend old_pointer make_old(old_value const&);
friend convertible_old make_old(virtual_*, unconvertible_old const&);
friend old_pointer make_old(virtual_*, old_value const&);
/** @endcond */
};
/**
Make a null old value copy (i.e., the related old value pointer will be null).
@see @RefSect{advanced_topics, Advanced Topics}.
Make a null old value copy.
The related old value pointer will always be null.
@see @RefSect{advanced_topics, Advanced Topics}
@return Null old value copy.
*/
unconvertible_old null_old() { return unconvertible_old(); }
old_value null_old() { return old_value(); }
/**
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}).
Make an old value pointer (not to be used for for virtual and overriding public
functions).
The related old value pointer will not be null if the specified old value was
actually copied.
@see @RefSect{advanced_topics, Advanced Topics}
@param old Old value (usually implicitly constructed from the user old value
expression to be copied).
@return Old value pointer (usually implicitly converted to either
@RefClass{boost::contract::old_ptr} or
@RefClass{boost::contract::old_ptr_noncopyable} in user code).
*/
convertible_old make_old(unconvertible_old const& old) {
return convertible_old(0, old);
old_pointer make_old(old_value const& old) {
return old_pointer(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}).
Make an old value pointer (to be used for virtual and overriding public
functions).
The related old value pointer will not be null if the specified old value was
actually copied.
@see @RefSect{advanced_topics, Advanced Topics}
@param v The contracted virtual and overriding function extra trailing
parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and
with default value @c 0.
@param old Old value (usually implicitly constructed from the user old value
expression to be copied).
@return Old value pointer (usually implicitly converted to either
@RefClass{boost::contract::old_ptr} or
@RefClass{boost::contract::old_ptr_noncopyable} in user code).
*/
convertible_old make_old(virtual_* v, unconvertible_old const& old) {
return convertible_old(v, old);
old_pointer make_old(virtual_* v, old_value const& old) {
return old_pointer(v, old);
}
/**
Return true if and only if old values need to be copied (for non virtual and
not overriding public functions).
Check if old values need to be copied (not to be used 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}.
@see @RefSect{advanced_topics, Advanced Topics}
@return True if old values are being copied, false otherwise.
*/
bool copy_old() {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
@@ -457,12 +498,15 @@ bool copy_old() {
}
/**
Return true if and only if old values need to be copied (for virtual and
overriding public functions).
Check if old values need to be copied (to be used 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.
@see @RefSect{advanced_topics, Advanced Topics}
@param v The contracted virtual and overriding function extra trailing
parameter of type @RefClass{boost::contract::virtual_}<c>*</c> and
with default value @c 0.
@return True if old values are being copied, false otherwise.
*/
bool copy_old(virtual_* v) {
#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS

View File

@@ -8,7 +8,8 @@
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
/** @file
Support contracts for overriding public functions.
Facilities to specify contracts for overriding public functions (to support
subcontracting).
*/
#include <boost/contract/detail/all_core_headers.hpp>
@@ -84,15 +85,15 @@ Support contracts for overriding public functions.
};
#else
/**
Declare override type allowing to explicitly specify its name.
Declare override type to be passed as an explicit template parameter to
Declare an override type with an arbitrary name.
Declare the 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.
@see @RefSect{tutorial, Tutorial}
@param override_name Name of override type to declare.
@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
for all functions in the same overload set (see
@RefSect{advanced_topics, Advanced Topics}).
*/
#define BOOST_CONTRACT_NAMED_OVERRIDE(override_name, function_name) \
@@ -102,14 +103,14 @@ Support contracts for overriding public functions.
/* PUBLIC */
/**
Declare override type naming it <c>override_<e>function_name</e></c>.
Declare override type to be passed as an explicit template parameter to
Declare an override type naming it <c>override_<i>function_name</i></c>.
Declare the override type to be passed as an explicit template parameter to
@RefFunc{boost::contract::public_function} for overriding public functions.
@see @RefSect{tutorial, Tutorial}.
@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
for all functions in the same overload set (see
@RefSect{advanced_topics, Advanced Topics}).
*/
#define BOOST_CONTRACT_OVERRIDE(function_name) \
@@ -130,14 +131,14 @@ Declare override type to be passed as an explicit template parameter to
/* 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}.
Declare multiple override types at once naming them <c>override_...</c> (for
convenience).
This is a variadic macro. On compilers that do not support variadic macros,
the override types can be programmed one-by-one calling
@RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name.
@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.
public functions.
*/
#define BOOST_CONTRACT_OVERRIDES(...) \
BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \

View File

@@ -9,8 +9,8 @@
/** @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.
Overloads are provided to handle static, virtual void, virtual non-void,
overriding void, and override 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.
@@ -44,68 +44,79 @@ overriding void/non-void public functions.
namespace boost { namespace contract {
// NOTE: O and (optionally) R allowed only when v is present because:
// NOTE: Override and (optionally) VirtualResult allowed only when v is present
// because:
// * An overriding func must override a base func declared virtual so with
// v extra param, thus the overriding func must also always have v (i.e., O
// might be present only if v is also present).
// However, the first appearing virtual func (e.g., in root class) will not
// override any previously declared virtual func so does not need O (i.e., O
// v extra param, thus the overriding func must also always have v (i.e.,
// Override might be present only if v is also present). However, the first
// appearing virtual func (e.g., in root class) will not override any
// previously declared virtual func so does not need Override (i.e., Override
// always optional).
// Furthermore, F needs to be specified only together with O.
// * R is only used for virtual functions (i.e., R might be present only if v
// is also present).
// However, R is never specified, not even for virtual functions, when the
// return type is void (i.e., R always optional).
// Furthermore, F needs to be specified only together with Override.
// * VirtualResult is only used for virtual functions (i.e., VirtualResult might
// be present only if v is also present).
// However, VirtualResult is never specified, not even for virtual functions,
// when the return type is void (i.e., VirtualResult always optional).
/**
Program contracts for static public functions.
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).
This is used to specify preconditions, postconditions, old value assignments at
body, and check static class invariants for static public functions.
For optimization, this can be omitted for static public functions that do not
have preconditions and postconditions when the enclosing class has no static
invariants.
@see @RefSect{tutorial, Tutorial}
@tparam Class The class of the contracted member function. This template
parameter must be explicitly specified for static public
functions (because they have no object @c this so there is no
function argument from which this type template parameter can be
automatically deduced).
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the body
of the contracted function (otherwise this library will generate a
run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class C>
set_precondition_old_postcondition<> public_function() {
template<class Class>
specify_precondition_old_postcondition<> public_function() {
#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
return set_precondition_old_postcondition<>(
new boost::contract::detail::public_static_function<C>());
return specify_precondition_old_postcondition<>(
new boost::contract::detail::public_static_function<Class>());
#else
return set_precondition_old_postcondition<>();
return specify_precondition_old_postcondition<>();
#endif
}
/**
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).
This is used to specify preconditions, postconditions, old value assignments at
body, and check class invariants for public functions that are not static, not
virtual, and do not override.
For optimization, this can be omitted for public functions that do not have
preconditions and postconditions when the enclosing class has no (non-static)
invariants.
@see @RefSect{tutorial, Tutorial}
@param obj The object @c this from the scope of the contracted function. This
object can be @c const and @c volatile depending on the
cv-qualifier for the contracted 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 variable of type
@RefClass{boost::contract::guard} declared locally just before the body
of the contracted function (otherwise this library will generate a
run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class C>
set_precondition_old_postcondition<> public_function(C* obj) {
template<class Class>
specify_precondition_old_postcondition<> public_function(Class* obj) {
#ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
return set_precondition_old_postcondition<>(
return specify_precondition_old_postcondition<>(
new boost::contract::detail::public_function<
boost::contract::detail::none,
boost::contract::detail::none,
boost::contract::detail::none,
C
Class
BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
BOOST_CONTRACT_MAX_ARGS)
BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
@@ -125,7 +136,7 @@ set_precondition_old_postcondition<> public_function(C* obj) {
)
);
#else
return set_precondition_old_postcondition<>();
return specify_precondition_old_postcondition<>();
#endif
}
@@ -138,34 +149,36 @@ set_precondition_old_postcondition<> public_function(C* obj) {
#define BOOST_CONTRACT_PUBLIC_FUNCTIONS_ 1
#endif
// TODO: Document no F here so cannot check consistency between R and actual func's result type... up to user to pass the right R...
// TODO: Document no F here so cannot check consistency between VirtualResult and actual func's result type... up to user to pass the right VirtualResult...
// For non-static, virtual, and non-overriding public functions (PRIVATE macro).
#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(has_result) \
#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \
has_virtual_result) \
template< \
BOOST_PP_EXPR_IIF(has_result, typename R) \
BOOST_PP_COMMA_IF(has_result) \
class C \
BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \
BOOST_PP_COMMA_IF(has_virtual_result) \
class Class \
> \
set_precondition_old_postcondition<BOOST_PP_EXPR_IIF(has_result, R)> \
specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \
public_function( \
virtual_* v \
BOOST_PP_COMMA_IF(has_result) \
BOOST_PP_EXPR_IIF(has_result, R& r) \
, C* obj \
BOOST_PP_COMMA_IF(has_virtual_result) \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \
, Class* obj \
) { \
BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_, \
/* no F... so cannot enforce contracted F ret R (up to user) */ \
return (set_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, R)>( \
/* no F... so cannot enforce contracted F returns VirtualResult */ \
return (specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
new boost::contract::detail::public_function< \
boost::contract::detail::none, \
BOOST_PP_IIF(has_result, \
R \
BOOST_PP_IIF(has_virtual_result, \
VirtualResult \
, \
boost::contract::detail::none \
), \
boost::contract::detail::none, \
C \
Class \
BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
BOOST_CONTRACT_MAX_ARGS) \
BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
@@ -175,7 +188,7 @@ set_precondition_old_postcondition<> public_function(C* obj) {
>( \
v, \
obj, \
BOOST_PP_IIF(has_result, \
BOOST_PP_IIF(has_virtual_result, \
r \
, \
boost::contract::detail::none::value() \
@@ -189,8 +202,8 @@ set_precondition_old_postcondition<> public_function(C* obj) {
) \
)); \
, \
return set_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, R)>(); \
return specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
) \
}
@@ -198,68 +211,81 @@ set_precondition_old_postcondition<> public_function(C* obj) {
#ifdef DOXYGEN
/**
Program contracts for virtual but not overriding public functions returning
Program contracts for virtual, 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}.
This is used to specify preconditions, postconditions, old value assignments
at body, and check class invariants for public functions that are virtual,
do not override, and return @c void.
For optimization, this can be omitted for public functions that do not have
preconditions and postconditions when the enclosing class has no
(non-static) invariants.
@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
@param obj The object @c this from the scope of the contracted function.
This object can be @c const and @c volatile depending on the
cv-qualifier for the contracted 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).
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the
body of the contracted function (otherwise this library will
generate a run-time error, see
@RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class C>
set_precondition_old_postcondition<> public_function(virtual_* v, C* obj);
template<class Class>
specify_precondition_old_postcondition<> public_function(virtual_* v,
Class* obj);
/**
Program contracts for virtual but not overriding public functions returning
Program contracts for virtual, 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}.
This is used to specify preconditions, postconditions, old value assignments
at body, and check class invariants for public functions that are virtual,
do not override, and do not return @c void.
For optimization, this can be omitted for public functions that do not have
preconditions and postconditions when the enclosing class has no
(non-static) invariants.
@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
(This can be a local variable within 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
@param obj The object @c this from the scope of the contracted function.
This object can be @c const and @c volatile depending on the
cv-qualifier for the contracted 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).
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the
body of the contracted function (otherwise this library will
generate a run-time error, see
@RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<typename R, class C>
set_precondition_old_postcondition<R> public_function(
virtual_* v, R& r, C* obj);
template<typename VirtualResult, class Class>
specify_precondition_old_postcondition<VirtualResult> public_function(
virtual_* v, VirtualResult& r, Class* obj);
#else
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 0)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(/* has_result = */ 1)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
/* has_virtual_result = */ 0)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
/* has_virtual_result = */ 1)
#endif
/** @cond */
// For non-static, virtual, and overriding public functions (PRIVATE macro).
#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
z, arity, arity_compl, has_result) \
z, arity, arity_compl, has_virtual_result) \
BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
arity, /* is_friend = */ 0, has_result, \
O, R, F, C, Args, \
arity, /* is_friend = */ 0, has_virtual_result, \
Override, VirtualResult, F, Class, Args, \
v, r, f, obj, args \
) { \
BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_, \
@@ -271,8 +297,8 @@ set_precondition_old_postcondition<> public_function(C* obj) {
BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args), \
"missing one or more arguments for specified function" \
); \
/* assert consistency of F's result type and R (if has_result) */ \
BOOST_PP_IIF(has_result, \
/* assert consistency of F's result type and VirtualResult */ \
BOOST_PP_IIF(has_virtual_result, \
BOOST_STATIC_ASSERT_MSG \
, \
BOOST_PP_TUPLE_EAT(2) \
@@ -281,26 +307,26 @@ set_precondition_old_postcondition<> public_function(C* obj) {
typename boost::remove_reference<typename boost:: \
function_types::result_type<F>::type>::type, \
typename boost::contract::detail:: \
remove_value_reference_if_optional<R>::type \
remove_value_reference_if_optional<VirtualResult>::type\
>::value), \
"mismatching result type for specified function" \
); \
/* assert this so lib can check and enforce override */ \
BOOST_STATIC_ASSERT_MSG( \
boost::contract::access::has_base_types<C>::value, \
boost::contract::access::has_base_types<Class>::value, \
"enclosing class missing 'base-types' typedef" \
); \
return (set_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, R)>( \
return (specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
new boost::contract::detail::public_function< \
O, \
BOOST_PP_IIF(has_result, \
R \
Override, \
BOOST_PP_IIF(has_virtual_result, \
VirtualResult \
, \
boost::contract::detail::none \
), \
F, \
C \
Class \
BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \
BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
@@ -309,7 +335,7 @@ set_precondition_old_postcondition<> public_function(C* obj) {
>( \
v, \
obj, \
BOOST_PP_IIF(has_result, \
BOOST_PP_IIF(has_virtual_result, \
r \
, \
boost::contract::detail::none::value() \
@@ -322,8 +348,8 @@ set_precondition_old_postcondition<> public_function(C* obj) {
) \
)); \
, \
return set_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_result, R)>(); \
return specify_precondition_old_postcondition< \
BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
) \
}
@@ -331,87 +357,100 @@ set_precondition_old_postcondition<> public_function(C* obj) {
#ifdef DOXYGEN
/**
Program contracts for overriding (virtual or not) public functions returning
Program contracts for overriding public functions (virtual or not) 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}.
This is used to specify preconditions, postconditions, old value assignments
at body, and check class invariants for overriding public functions (virtual
or not) that return @c void.
For optimization, this can be omitted for public functions that do not have
preconditions and postconditions when the enclosing class has no
(non-static) invariants.
@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
@param obj The object @c this from the scope of the contracted function.
This object can be @c const and @c volatile depending on the
cv-qualifier for the contracted 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
@param args The contracted function arguments (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).
@tparam Override The type @c override_... declared using the
@RefMacro{BOOST_CONTRACT_OVERRIDE} (or similar) macro
using the contracted function name. This template
parameter must be explicitly specified (because there is
no function arguments from which this type template
parameter can be automatically deduced).
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the
body of the contracted function (otherwise this library will
generate a run-time error, see
@RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
template<class O, typename F, class C, typename... Args>
set_precondition_old_postcondition<> public_function(
virtual_* v, F f, C* obj, Args&... args);
template<class Override, typename F, class Class, typename... Args>
specify_precondition_old_postcondition<> public_function(
virtual_* v, F f, Class* obj, Args&... args);
/**
Program contracts for overriding (virtual or not) public functions returning
Program contracts for overriding public functions (virtual or not) 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}.
This is used to specify preconditions, postconditions, old value assignments
at body, and check class invariants for overriding public functions (virtual
or not) that do not return @c void.
For optimization, this can be omitted for public functions that do not have
preconditions and postconditions when the enclosing class has no
(non-static) invariants.
@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
(This can be a local variable within 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
@param obj The object @c this from the scope of the contracted function.
This object can be @c const and @c volatile depending on the
cv-qualifier for the contracted 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
@param args The contracted function arguments (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).
@tparam Override The type @c override_... declared using the
@RefMacro{BOOST_CONTRACT_OVERRIDE} (or similar) macro
using the contracted function name. This template
parameter must be explicitly specified (because there is
no function arguments from which this type template
parameter can be automatically deduced).
@return The result of this function must be assigned to a variable of type
@RefClass{boost::contract::guard} declared locally just before the
body of the contracted function (otherwise this library will
generate a run-time error, see
@RefMacro{BOOST_CONTRACT_ON_MISSING_GUARD}).
*/
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);
template<class Override, typename VirtualResult, typename F, class Class,
typename... Args>
specify_precondition_old_postcondition<VirtualResult> public_function(
virtual_* v, VirtualResult& r, F f, Class* obj, Args&... args);
#elif BOOST_CONTRACT_DETAIL_TVARIADIC
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1,
/* arity = */ ~, /* arity_compl = */ ~, /* has_result = */ 0)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1,
/* arity = */ ~, /* arity_compl = */ ~, /* has_result = */ 1)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
/* arity_compl = */ ~, /* has_virtual_result = */ 0)
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
/* arity_compl = */ ~, /* has_virtual_result = */ 1)
#else
/* PRIVATE */
@@ -423,9 +462,9 @@ set_precondition_old_postcondition<> public_function(C* obj) {
#define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \
arity, arity_compl, unused) \
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
arity, arity_compl, /* has_result = */ 0) \
arity, arity_compl, /* has_virtual_result = */ 0) \
BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
arity, arity_compl, /* has_result = */ 1)
arity, arity_compl, /* has_virtual_result = */ 1)
/* CODE */