123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883 |
- #ifndef BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
- #define BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
- // Copyright (C) 2008-2018 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0 (see accompanying
- // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
- // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
- /** @file
- Program contracts for public functions (including subcontracting).
- The different overloads handle public functions that are static, virtual void,
- virtual non-void, overriding void, and overriding non-void.
- */
- #include <boost/contract/core/config.hpp>
- #include <boost/contract/core/specify.hpp>
- #include <boost/contract/core/access.hpp>
- #include <boost/contract/core/virtual.hpp>
- /** @cond */
- // Needed within macro expansions below instead of defined(...) (PRIVATE macro).
- #if !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) || \
- defined(BOOST_CONTRACT_STATIC_LINK)
- #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 1
- #else
- #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 0
- #endif
- /** @endcond */
- #include <boost/contract/detail/decl.hpp>
- #include <boost/contract/detail/tvariadic.hpp>
- #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
- #include <boost/contract/detail/operation/static_public_function.hpp>
- #include <boost/contract/detail/operation/public_function.hpp>
- #include <boost/contract/detail/type_traits/optional.hpp>
- #include <boost/contract/detail/none.hpp>
- #include <boost/function_types/result_type.hpp>
- #include <boost/function_types/function_arity.hpp>
- #include <boost/optional.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/preprocessor/tuple/eat.hpp>
- #endif
- #if !BOOST_CONTRACT_DETAIL_TVARIADIC
- #include <boost/preprocessor/repetition/repeat.hpp>
- #include <boost/preprocessor/arithmetic/sub.hpp>
- #include <boost/preprocessor/arithmetic/inc.hpp>
- #endif
- #include <boost/preprocessor/control/expr_iif.hpp>
- #include <boost/preprocessor/control/iif.hpp>
- #include <boost/preprocessor/facilities/empty.hpp>
- #include <boost/preprocessor/punctuation/comma_if.hpp>
- namespace boost { namespace contract {
- // NOTE: Override and (optionally) VirtualResult allowed only when v is present
- // because:
- // * An overriding func must override a base func declared virtual so with
- // v extra param, thus the overriding func must also always have v (i.e.,
- // Override might be present only if v is also present). However, the first
- // appearing virtual func (e.g., in root class) will not override any
- // previously declared virtual func so does not need Override (i.e., Override
- // always optional).
- // Furthermore, F needs to be specified only together with Override.
- // * VirtualResult is only used for virtual functions (i.e., VirtualResult might
- // be present only if v is also present).
- // However, VirtualResult is never specified, not even for virtual functions,
- // when the return type is void (i.e., VirtualResult always optional).
- /**
- Program contracts for static public functions.
- This is used to specify preconditions, postconditions, exception guarantees, old
- value copies at body, and check static class invariants for static public
- functions:
- @code
- class u {
- friend class boost::contract::access;
- static void static_invariant() { // Optional (as for non-static).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- public:
- static void f(...) {
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function<u>()
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(old_expr);
- ...
- })
- .postcondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body.
- }
-
- ...
- };
- @endcode
- For optimization, this can be omitted for static public functions that do not
- have preconditions, postconditions and exception guarantees, within classes that
- have no static invariants.
- @see @RefSect{tutorial.static_public_functions, Static Public Functions}
- @tparam Class The type of the class containing the static public function
- declaring the contract.
- This template parameter must be explicitly specified for static
- public functions (because they have no object @c this so there
- is no function argument from which this type template parameter
- can be automatically deduced by C++).
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code of
- the static public function body (otherwise this library will generate a
- run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<class Class>
- specify_precondition_old_postcondition_except<> public_function() {
- #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
- return specify_precondition_old_postcondition_except<>(
- new boost::contract::detail::static_public_function<Class>());
- #else
- return specify_precondition_old_postcondition_except<>();
- #endif
- }
- /**
- Program contracts for public functions that are not static, not virtual, and do
- not not override.
- This is used to specify preconditions, postconditions, exception guarantees, old
- value copies at body, and check class invariants for public functions that are
- not static, not virtual, and do not override:
- @code
- class u {
- friend class boost::contract::access;
- void invariant() const { // Optional (as for static and volatile).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- public:
- void f(...) {
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function(this)
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(old_expr);
- ...
- })
- .postcondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body.
- }
-
- ...
- };
- @endcode
- For optimization, this can be omitted for public functions that do not have
- preconditions, postconditions and exception guarantees, within classes that have
- no invariants.
- @see @RefSect{tutorial.public_functions, Public Functions}
- @param obj The object @c this from the scope of the enclosing public function
- declaring the contract.
- This object might be mutable, @c const, @c volatile, or
- <c>const volatile</c> depending on the cv-qualifier of the enclosing
- function (volatile public functions will check volatile class
- invariants, see
- @RefSect{extras.volatile_public_functions,
- Volatile Public Functions}).
- @tparam Class The type of the class containing the public function declaring
- the contract.
- (Usually this template parameter is automatically deduced by C++
- and it does not need to be explicitly specified by programmers.)
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code of
- the public function body (otherwise this library will generate a
- run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<class Class>
- specify_precondition_old_postcondition_except<> public_function(Class* obj) {
- #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
- return specify_precondition_old_postcondition_except<>(
- new boost::contract::detail::public_function<
- boost::contract::detail::none,
- boost::contract::detail::none,
- boost::contract::detail::none,
- Class
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
- BOOST_CONTRACT_MAX_ARGS)
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
- BOOST_CONTRACT_MAX_ARGS,
- boost::contract::detail::none
- )
- >(
- static_cast<boost::contract::virtual_*>(0),
- obj,
- boost::contract::detail::none::value()
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
- BOOST_CONTRACT_MAX_ARGS)
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
- BOOST_CONTRACT_MAX_ARGS,
- boost::contract::detail::none::value()
- )
- )
- );
- #else
- return specify_precondition_old_postcondition_except<>();
- #endif
- }
- /** @cond */
- // For non-static, virtual, and non-overriding public functions (PRIVATE macro).
- #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \
- has_virtual_result) \
- template< \
- BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \
- BOOST_PP_COMMA_IF(has_virtual_result) \
- class Class \
- > \
- specify_precondition_old_postcondition_except< \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \
- public_function( \
- virtual_* v \
- BOOST_PP_COMMA_IF(has_virtual_result) \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \
- , Class* obj \
- ) { \
- BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
- /* no F... so cannot enforce contracted F returns VirtualResult */ \
- return (specify_precondition_old_postcondition_except< \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
- new boost::contract::detail::public_function< \
- boost::contract::detail::none, \
- BOOST_PP_IIF(has_virtual_result, \
- VirtualResult \
- , \
- boost::contract::detail::none \
- ), \
- boost::contract::detail::none, \
- Class \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
- BOOST_CONTRACT_MAX_ARGS) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
- BOOST_CONTRACT_MAX_ARGS, \
- boost::contract::detail::none \
- ) \
- >( \
- v, \
- obj, \
- BOOST_PP_IIF(has_virtual_result, \
- r \
- , \
- boost::contract::detail::none::value() \
- ) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
- BOOST_CONTRACT_MAX_ARGS) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
- BOOST_CONTRACT_MAX_ARGS, \
- boost::contract::detail::none::value() \
- ) \
- ) \
- )); \
- , \
- return specify_precondition_old_postcondition_except< \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
- ) \
- }
- /** @endcond */
-
- #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
- /**
- Program contracts for void virtual public functions that do not override.
- This is used to specify preconditions, postconditions, exception guarantees,
- old value copies at body, and check class invariants for public functions
- that are virtual, do not override, and return @c void:
- @code
- class u {
- friend class boost::contract::access;
- void invariant() const { // Optional (as for static and volatile).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- public:
- void f(..., boost::contract::virtual_* v = 0) {
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function(v, this)
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
- ...
- })
- .postcondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body.
- }
-
- ...
- };
- @endcode
- A virtual public function should always call
- @RefFunc{boost::contract::public_function} otherwise this library will not
- be able to correctly use it for subcontracting.
- @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
-
- @param v The trailing parameter of type
- @RefClass{boost::contract::virtual_}<c>*</c> and default value
- @c 0 from the enclosing virtual public function.
- @param obj The object @c this from the scope of the enclosing virtual
- public function declaring the contract.
- This object might be mutable, @c const, @c volatile, or
- <c>const volatile</c> depending on the cv-qualifier of the
- enclosing function (volatile public functions will check
- volatile class invariants, see
- @RefSect{extras.volatile_public_functions,
- Volatile Public Functions}).
- @tparam Class The type of the class containing the virtual public function
- declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
-
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code
- of the public function body (otherwise this library will generate a
- run-time error, see
- @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<class Class>
- specify_precondition_old_postcondition_except<> public_function(
- virtual_* v, Class* obj);
-
- /**
- Program contracts for non-void virtual public functions that do not
- override.
- This is used to specify preconditions, postconditions, exception guarantees,
- old value copies at body, and check class invariants for public functions
- that are virtual, do not override, and do not return @c void:
-
- @code
- class u {
- friend class boost::contract::access;
- void invariant() const { // Optional (as for static and volatile).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- public:
- t f(..., boost::contract::virtual_* v = 0) {
- t result;
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function(
- v, result, this)
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
- ...
- })
- .postcondition([&] (t const& result) { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body (use `return result = return_expr`).
- }
-
- ...
- };
- @endcode
- A virtual public function should always call
- @RefFunc{boost::contract::public_function} otherwise this library will not
- be able to correctly use it for subcontracting.
- @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
-
- @param v The trailing parameter of type
- @RefClass{boost::contract::virtual_}<c>*</c> and default value
- @c 0 from the enclosing virtual public function.
- @param r A reference to the return value of the enclosing virtual public
- function declaring the contract.
- This is usually a local variable declared by the enclosing
- virtual public function just before the contract, but
- programmers must set it to the actual value being returned by
- the function at each @c return statement.
- @param obj The object @c this from the scope of the enclosing virtual
- public function declaring the contract.
- This object might be mutable, @c const, @c volatile, or
- <c>const volatile</c> depending on the cv-qualifier of the
- enclosing function (volatile public functions will check
- volatile class invariants, see
- @RefSect{extras.volatile_public_functions,
- Volatile Public Functions}).
-
- @tparam VirtualResult This type must be the same as, or compatible with,
- the return type of the enclosing virtual public
- function declaring the contract (this library might
- not be able to generate a compile-time error if
- these types mismatch, but in general that will cause
- run-time errors or undefined behaviour).
- Alternatively,
- <c>boost::optional<<i>return-type</i>></c> can also
- be used (see
- @RefSect{advanced.optional_return_values,
- Optional Return Values}).
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- @tparam Class The type of the class containing the virtual public function
- declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
-
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code
- of the public function body (otherwise this library will generate a
- run-time error, see
- @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<typename VirtualResult, class Class>
- specify_precondition_old_postcondition_except<VirtualResult>
- public_function(virtual_* v, VirtualResult& r, Class* obj);
- #else
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
- /* has_virtual_result = */ 0)
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
- /* has_virtual_result = */ 1)
- #endif
- /** @cond */
- // For non-static, virtual, and overriding public functions (PRIVATE macro).
- #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
- z, arity, arity_compl, has_virtual_result) \
- BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
- arity, /* is_friend = */ 0, has_virtual_result, \
- Override, VirtualResult, F, Class, Args, \
- v, r, /* f */ BOOST_PP_EMPTY(), obj, args \
- ) { \
- BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
- { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
- /* assert not strictly necessary as compilation will fail */ \
- /* anyways, but helps limiting cryptic compiler's errors */ \
- BOOST_STATIC_ASSERT_MSG( \
- /* -2 for both `this` and `virtual_*` extra parameters */ \
- ( \
- boost::function_types::function_arity<F>::value - 2 \
- == \
- BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args) \
- ), \
- "missing one or more arguments for specified function" \
- ); \
- } \
- { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
- /* assert consistency of F's result type and VirtualResult */ \
- BOOST_PP_IIF(has_virtual_result, \
- BOOST_STATIC_ASSERT_MSG \
- , \
- BOOST_PP_TUPLE_EAT(2) \
- )( \
- (boost::is_same< \
- typename boost::remove_reference<typename boost:: \
- function_types::result_type<F>::type>::type, \
- typename boost::contract::detail:: \
- remove_value_reference_if_optional< \
- VirtualResult \
- >::type \
- >::value), \
- "mismatching result type for specified function" \
- ); \
- } \
- { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
- /* assert this so lib can check and enforce override */ \
- BOOST_STATIC_ASSERT_MSG( \
- boost::contract::access::has_base_types<Class>::value, \
- "enclosing class missing 'base-types' typedef" \
- ); \
- } \
- return (specify_precondition_old_postcondition_except< \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
- new boost::contract::detail::public_function< \
- Override, \
- BOOST_PP_IIF(has_virtual_result, \
- VirtualResult \
- , \
- boost::contract::detail::none \
- ), \
- F, \
- Class \
- BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
- BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
- boost::contract::detail::none) \
- >( \
- v, \
- obj, \
- BOOST_PP_IIF(has_virtual_result, \
- r \
- , \
- boost::contract::detail::none::value() \
- ) \
- BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
- BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, args) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
- BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
- boost::contract::detail::none::value()) \
- ) \
- )); \
- , \
- return specify_precondition_old_postcondition_except< \
- BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
- ) \
- }
- /** @endcond */
- #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
- /**
- Program contracts for void public functions overrides (virtual or not).
- This is used to specify preconditions, postconditions, exception guarantees,
- old value copies at body, and check class invariants for public function
- overrides (virtual or not) that return @c void:
-
- @code
- class u
- #define BASES private boost::contract::constructor_precondition<u>, \
- public b, private w
- : BASES
- {
- friend class boost::contract::access;
- typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
- #undef BASES
- void invariant() const { // Optional (as for static and volatile).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- BOOST_CONTRACT_OVERRIDES(f)
- public:
- // Override from `b::f`.
- void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function<
- override_f>(v, &u::f, this, a_1, ..., a_n)
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
- ...
- })
- .postcondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body.
- }
-
- ...
- };
- @endcode
- A public function override should always call
- @RefFunc{boost::contract::public_function} otherwise this library will not
- be able to correctly use it for subcontracting.
- @see @RefSect{tutorial.public_function_overrides__subcontracting_,
- Public Function Overrides}
-
- @param v The trailing parameter of type
- @RefClass{boost::contract::virtual_}<c>*</c> and default value
- @c 0 from the enclosing public function override.
- @param f A pointer to the enclosing public function override declaring
- the contract (but see @RefSect{advanced.function_overloads,
- Function Overloads}).
- @param obj The object @c this from the scope of the enclosing public
- function override declaring the contract.
- This object might be mutable, @c const, @c volatile, or
- <c>const volatile</c> depending on the cv-qualifier of the
- enclosing function (volatile public functions will check
- volatile class invariants, see
- @RefSect{extras.volatile_public_functions,
- Volatile Public Functions}).
- @param args All arguments passed to the enclosing public function override
- declaring the contract (by reference and in the order they
- appear in the enclosing function declaration), but excluding the
- trailing argument @c v.
- @tparam Override The type trait <c>override_<i>function-name</i></c>
- declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
- related macros.
- This template parameter must be explicitly specified
- (because there is no function argument from which it can
- be automatically deduced by C++).
- @tparam F The function pointer type of the enclosing public function
- override declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
- @tparam Class The type of the class containing the virtual public function
- declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
- @tparam Args The types of all parameters passed to the enclosing public
- function override declaring the contract, but excluding the
- trailing parameter type <c>boost::contract::virtual_*</c>.
- On compilers that do not support variadic templates, this
- library internally implements this function using
- preprocessor meta-programming (in this case, the maximum
- number of supported arguments is defined by
- @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
- (Usually these template parameters are automatically deduced
- by C++ and they do not need to be explicitly specified by
- programmers.)
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code
- of the public function body (otherwise this library will generate a
- run-time error, see
- @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<class Override, typename F, class Class, typename... Args>
- specify_precondition_old_postcondition_except<> public_function(
- virtual_* v, F f, Class* obj, Args&... args);
- /**
- Program contracts for non-void public functions overrides (virtual or not).
- This is used to specify preconditions, postconditions, exception guarantees,
- old value copies at body, and check class invariants for public function
- overrides (virtual or not) that do not return @c void:
-
- @code
- class u
- #define BASES private boost::contract::constructor_precondition<u>, \
- public b, private w
- : BASES
- {
- friend class boost::contract::access;
- typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
- #undef BASES
- void invariant() const { // Optional (as for static and volatile).
- BOOST_CONTRACT_ASSERT(...);
- ...
- }
- BOOST_CONTRACT_OVERRIDES(f)
- public:
- // Override from `b::f`.
- t f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
- t result;
- boost::contract::old_ptr<old_type> old_var;
- boost::contract::check c = boost::contract::public_function<
- override_f>(v, result, &u::f, this, a_1, ..., a_n)
- .precondition([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .old([&] { // Optional.
- old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
- ...
- })
- .postcondition([&] (t const& result) { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- .except([&] { // Optional.
- BOOST_CONTRACT_ASSERT(...);
- ...
- })
- ;
- ... // Function body (use `return result = return_expr`).
- }
-
- ...
- };
- @endcode
- A public function override should always call
- @RefFunc{boost::contract::public_function} otherwise this library will not
- be able to correctly use it for subcontracting.
- @see @RefSect{tutorial.public_function_overrides__subcontracting_,
- Public Function Overrides}
-
- @param v The trailing parameter of type
- @RefClass{boost::contract::virtual_}<c>*</c> and default value
- @c 0 from the enclosing public function override.
- @param r A reference to the return value of the enclosing public function
- override declaring the contract.
- This is usually a local variable declared by the enclosing
- public function override just before the contract, but
- programmers must set it to the actual value being returned by
- the function at each @c return statement.
- @param f A pointer to the enclosing public function override declaring
- the contract (but see @RefSect{advanced.function_overloads,
- Function Overloads}).
- @param obj The object @c this from the scope of the enclosing public
- function override declaring the contract.
- This object might be mutable, @c const, @c volatile, or
- <c>const volatile</c> depending on the cv-qualifier of the
- enclosing function (volatile public functions will check
- volatile class invariants, see
- @RefSect{extras.volatile_public_functions,
- Volatile Public Functions}).
- @param args All arguments passed to the enclosing public function override
- declaring the contract (by reference and in the order they
- appear in the enclosing function declaration), but excluding the
- trailing argument @c v.
- @tparam Override The type trait <c>override_<i>function-name</i></c>
- declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
- related macros.
- This template parameter must be explicitly specified
- (because there is no function argument from which it can
- be automatically deduced by C++).
- @tparam VirtualResult This type must be the same as, or compatible with,
- the return type of the enclosing public function
- override declaring the contract (this library might
- not be able to generate a compile-time error if
- these types mismatch, but in general that will cause
- run-time errors or undefined behaviour).
- Alternatively,
- <c>boost::optional<<i>return-type</i>></c> can also
- be used (see
- @RefSect{advanced.optional_return_values,
- Optional Return Values}).
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- @tparam F The function pointer type of the enclosing public function
- override declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
- @tparam Class The type of the class containing the virtual public function
- declaring the contract.
- (Usually this template parameter is automatically deduced by
- C++ and it does not need to be explicitly specified by
- programmers.)
- @tparam Args The types of all parameters passed to the enclosing public
- function override declaring the contract, but excluding the
- trailing parameter type <c>boost::contract::virtual_*</c>.
- On compilers that do not support variadic templates, this
- library internally implements this function using
- preprocessor meta-programming (in this case, the maximum
- number of supported arguments is defined by
- @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
- (Usually these template parameters are automatically deduced
- by C++ and they do not need to be explicitly specified by
- programmers.)
- @return The result of this function must be assigned to a variable of type
- @RefClass{boost::contract::check} declared explicitly (i.e., without
- using C++11 @c auto declarations) and locally just before the code
- of the public function body (otherwise this library will generate a
- run-time error, see
- @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
- */
- template<class Override, typename VirtualResult, typename F, class Class,
- typename... Args>
- specify_precondition_old_postcondition_except<VirtualResult>
- public_function(virtual_* v, VirtualResult& r, F f, Class* obj,
- Args&... args);
- #elif BOOST_CONTRACT_DETAIL_TVARIADIC
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
- /* arity_compl = */ ~, /* has_virtual_result = */ 0)
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
- /* arity_compl = */ ~, /* has_virtual_result = */ 1)
- #else
- /* PRIVATE */
- #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_( \
- z, arity, unused) \
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, arity, \
- BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), ~)
-
- #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \
- arity, arity_compl, unused) \
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
- arity, arity_compl, /* has_virtual_result = */ 0) \
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
- arity, arity_compl, /* has_virtual_result = */ 1)
- /* CODE */
- BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
- BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_, ~)
- #endif
- } } // namespace
- #endif // #include guard
|