Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:03

0001 
0002 #ifndef BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
0003 #define BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
0004 
0005 // Copyright (C) 2008-2018 Lorenzo Caminiti
0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying
0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
0009 
0010 /** @file
0011 Program contracts for public functions (including subcontracting).
0012 The different overloads handle public functions that are static, virtual void,
0013 virtual non-void, overriding void, and overriding non-void.
0014 */
0015 
0016 #include <boost/contract/core/config.hpp>
0017 #include <boost/contract/core/specify.hpp>
0018 #include <boost/contract/core/access.hpp>
0019 #include <boost/contract/core/virtual.hpp>
0020 /** @cond */
0021 // Needed within macro expansions below instead of defined(...) (PRIVATE macro).
0022 #if !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) || \
0023         defined(BOOST_CONTRACT_STATIC_LINK)
0024     #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 1
0025 #else
0026     #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 0
0027 #endif
0028 /** @endcond */
0029 #include <boost/contract/detail/decl.hpp>
0030 #include <boost/contract/detail/tvariadic.hpp>
0031 #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
0032     #include <boost/contract/detail/operation/static_public_function.hpp>
0033     #include <boost/contract/detail/operation/public_function.hpp>
0034     #include <boost/contract/detail/type_traits/optional.hpp>
0035     #include <boost/contract/detail/none.hpp>
0036     #include <boost/function_types/result_type.hpp>
0037     #include <boost/function_types/function_arity.hpp>
0038     #include <boost/optional.hpp>
0039     #include <boost/type_traits/remove_reference.hpp>
0040     #include <boost/type_traits/is_same.hpp>
0041     #include <boost/static_assert.hpp>
0042     #include <boost/preprocessor/tuple/eat.hpp>
0043 #endif
0044 #if !BOOST_CONTRACT_DETAIL_TVARIADIC
0045     #include <boost/preprocessor/repetition/repeat.hpp>
0046     #include <boost/preprocessor/arithmetic/sub.hpp>
0047     #include <boost/preprocessor/arithmetic/inc.hpp>
0048 #endif
0049 #include <boost/preprocessor/control/expr_iif.hpp>
0050 #include <boost/preprocessor/control/iif.hpp>
0051 #include <boost/preprocessor/facilities/empty.hpp>
0052 #include <boost/preprocessor/punctuation/comma_if.hpp>
0053 
0054 namespace boost { namespace contract {
0055 
0056 // NOTE: Override and (optionally) VirtualResult allowed only when v is present
0057 // because:
0058 // * An overriding func must override a base func declared virtual so with
0059 //   v extra param, thus the overriding func must also always have v (i.e.,
0060 //   Override might be present only if v is also present). However, the first
0061 //   appearing virtual func (e.g., in root class) will not override any
0062 //   previously declared virtual func so does not need Override (i.e., Override
0063 //   always optional).
0064 //   Furthermore, F needs to be specified only together with Override.
0065 // * VirtualResult is only used for virtual functions (i.e., VirtualResult might
0066 //   be present only if v is also present).
0067 //   However, VirtualResult is never specified, not even for virtual functions,
0068 //   when the return type is void (i.e., VirtualResult always optional).
0069 
0070 /**
0071 Program contracts for static public functions.
0072 
0073 This is used to specify preconditions, postconditions, exception guarantees, old
0074 value copies at body, and check static class invariants for static public
0075 functions:
0076 
0077 @code
0078 class u {
0079     friend class boost::contract::access;
0080 
0081     static void static_invariant() { // Optional (as for non-static).
0082         BOOST_CONTRACT_ASSERT(...);
0083         ...
0084     }
0085 
0086 public:
0087     static void f(...) {
0088         boost::contract::old_ptr<old_type> old_var;
0089         boost::contract::check c = boost::contract::public_function<u>()
0090             .precondition([&] { // Optional.
0091                 BOOST_CONTRACT_ASSERT(...);
0092                 ...
0093             })
0094             .old([&] { // Optional.
0095                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
0096                 ...
0097             })
0098             .postcondition([&] { // Optional.
0099                 BOOST_CONTRACT_ASSERT(...);
0100                 ...
0101             })
0102             .except([&] { // Optional.
0103                 BOOST_CONTRACT_ASSERT(...);
0104                 ...
0105             })
0106         ;
0107 
0108         ... // Function body.
0109     }
0110     
0111     ...
0112 };
0113 @endcode
0114 
0115 For optimization, this can be omitted for static public functions that do not
0116 have preconditions, postconditions and exception guarantees, within classes that
0117 have no static invariants.
0118 
0119 @see @RefSect{tutorial.static_public_functions, Static Public Functions}
0120 
0121 @tparam Class   The type of the class containing the static public function
0122                 declaring the contract.
0123                 This template parameter must be explicitly specified for static
0124                 public functions (because they have no object @c this so there
0125                 is no function argument from which this type template parameter
0126                 can be automatically deduced by C++).
0127 
0128 @return The result of this function must be assigned to a variable of type
0129         @RefClass{boost::contract::check} declared explicitly (i.e., without
0130         using C++11 @c auto declarations) and locally just before the code of
0131         the static public function body (otherwise this library will generate a
0132         run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0133 */
0134 template<class Class>
0135 specify_precondition_old_postcondition_except<> public_function() {
0136     #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
0137         return specify_precondition_old_postcondition_except<>(
0138             new boost::contract::detail::static_public_function<Class>());
0139     #else
0140         return specify_precondition_old_postcondition_except<>();
0141     #endif
0142 }
0143 
0144 /**
0145 Program contracts for public functions that are not static, not virtual, and do
0146 not not override.
0147 
0148 This is used to specify preconditions, postconditions, exception guarantees, old
0149 value copies at body, and check class invariants for public functions that are
0150 not static, not virtual, and do not override:
0151 
0152 @code
0153 class u {
0154     friend class boost::contract::access;
0155 
0156     void invariant() const { // Optional (as for static and volatile).
0157         BOOST_CONTRACT_ASSERT(...);
0158         ...
0159     }
0160 
0161 public:
0162     void f(...) {
0163         boost::contract::old_ptr<old_type> old_var;
0164         boost::contract::check c = boost::contract::public_function(this)
0165             .precondition([&] { // Optional.
0166                 BOOST_CONTRACT_ASSERT(...);
0167                 ...
0168             })
0169             .old([&] { // Optional.
0170                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
0171                 ...
0172             })
0173             .postcondition([&] { // Optional.
0174                 BOOST_CONTRACT_ASSERT(...);
0175                 ...
0176             })
0177             .except([&] { // Optional.
0178                 BOOST_CONTRACT_ASSERT(...);
0179                 ...
0180             })
0181         ;
0182 
0183         ... // Function body.
0184     }
0185     
0186     ...
0187 };
0188 @endcode
0189 
0190 For optimization, this can be omitted for public functions that do not have
0191 preconditions, postconditions and exception guarantees, within classes that have
0192 no invariants.
0193 
0194 @see @RefSect{tutorial.public_functions, Public Functions}
0195 
0196 @param obj  The object @c this from the scope of the enclosing public function
0197             declaring the contract.
0198             This object might be mutable, @c const, @c volatile, or
0199             <c>const volatile</c> depending on the cv-qualifier of the enclosing
0200             function (volatile public functions will check volatile class
0201             invariants, see
0202             @RefSect{extras.volatile_public_functions,
0203             Volatile Public Functions}).
0204 
0205 @tparam Class   The type of the class containing the public function declaring
0206                 the contract.
0207                 (Usually this template parameter is automatically deduced by C++
0208                 and it does not need to be explicitly specified by programmers.)
0209 
0210 @return The result of this function must be assigned to a variable of type
0211         @RefClass{boost::contract::check} declared explicitly (i.e., without
0212         using C++11 @c auto declarations) and locally just before the code of
0213         the public function body (otherwise this library will generate a
0214         run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0215 */
0216 template<class Class>
0217 specify_precondition_old_postcondition_except<> public_function(Class* obj) {
0218     #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
0219         return specify_precondition_old_postcondition_except<>(
0220             new boost::contract::detail::public_function<
0221                 boost::contract::detail::none,
0222                 boost::contract::detail::none,
0223                 boost::contract::detail::none,
0224                 Class
0225                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
0226                         BOOST_CONTRACT_MAX_ARGS)
0227                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
0228                     BOOST_CONTRACT_MAX_ARGS,
0229                     boost::contract::detail::none
0230                 )
0231             >(
0232                 static_cast<boost::contract::virtual_*>(0),
0233                 obj,
0234                 boost::contract::detail::none::value()
0235                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
0236                         BOOST_CONTRACT_MAX_ARGS)
0237                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
0238                     BOOST_CONTRACT_MAX_ARGS,
0239                     boost::contract::detail::none::value()
0240                 )
0241             )
0242         );
0243     #else
0244         return specify_precondition_old_postcondition_except<>();
0245     #endif
0246 }
0247 
0248 /** @cond */
0249 
0250 // For non-static, virtual, and non-overriding public functions (PRIVATE macro).
0251 #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \
0252         has_virtual_result) \
0253     template< \
0254         BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \
0255         BOOST_PP_COMMA_IF(has_virtual_result) \
0256         class Class \
0257     > \
0258     specify_precondition_old_postcondition_except< \
0259             BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \
0260     public_function( \
0261         virtual_* v \
0262         BOOST_PP_COMMA_IF(has_virtual_result) \
0263         BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \
0264         , Class* obj \
0265     ) { \
0266         BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
0267             /* no F... so cannot enforce contracted F returns VirtualResult */ \
0268             return (specify_precondition_old_postcondition_except< \
0269                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
0270                 new boost::contract::detail::public_function< \
0271                     boost::contract::detail::none, \
0272                     BOOST_PP_IIF(has_virtual_result, \
0273                         VirtualResult \
0274                     , \
0275                         boost::contract::detail::none \
0276                     ), \
0277                     boost::contract::detail::none, \
0278                     Class \
0279                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
0280                             BOOST_CONTRACT_MAX_ARGS) \
0281                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
0282                         BOOST_CONTRACT_MAX_ARGS, \
0283                         boost::contract::detail::none \
0284                     ) \
0285                 >( \
0286                     v, \
0287                     obj, \
0288                     BOOST_PP_IIF(has_virtual_result, \
0289                         r \
0290                     , \
0291                         boost::contract::detail::none::value() \
0292                     ) \
0293                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
0294                             BOOST_CONTRACT_MAX_ARGS) \
0295                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
0296                         BOOST_CONTRACT_MAX_ARGS, \
0297                         boost::contract::detail::none::value() \
0298                     ) \
0299                 ) \
0300             )); \
0301         , \
0302             return specify_precondition_old_postcondition_except< \
0303                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
0304         ) \
0305     }
0306 
0307 /** @endcond */
0308     
0309 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0310     /**
0311     Program contracts for void virtual public functions that do not override.
0312 
0313     This is used to specify preconditions, postconditions, exception guarantees,
0314     old value copies at body, and check class invariants for public functions
0315     that are virtual, do not override, and return @c void:
0316 
0317     @code
0318     class u {
0319         friend class boost::contract::access;
0320 
0321         void invariant() const { // Optional (as for static and volatile).
0322             BOOST_CONTRACT_ASSERT(...);
0323             ...
0324         }
0325 
0326     public:
0327         void f(..., boost::contract::virtual_* v = 0) {
0328             boost::contract::old_ptr<old_type> old_var;
0329             boost::contract::check c = boost::contract::public_function(v, this)
0330                 .precondition([&] { // Optional.
0331                     BOOST_CONTRACT_ASSERT(...);
0332                     ...
0333                 })
0334                 .old([&] { // Optional.
0335                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
0336                     ...
0337                 })
0338                 .postcondition([&] { // Optional.
0339                     BOOST_CONTRACT_ASSERT(...);
0340                     ...
0341                 })
0342                 .except([&] { // Optional.
0343                     BOOST_CONTRACT_ASSERT(...);
0344                     ...
0345                 })
0346             ;
0347 
0348             ... // Function body.
0349         }
0350         
0351         ...
0352     };
0353     @endcode
0354 
0355     A virtual public function should always call
0356     @RefFunc{boost::contract::public_function} otherwise this library will not
0357     be able to correctly use it for subcontracting.
0358 
0359     @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
0360     
0361     @param v    The trailing parameter of type
0362                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
0363                 @c 0 from the enclosing virtual public function.
0364     @param obj  The object @c this from the scope of the enclosing virtual
0365                 public function declaring the contract.
0366                 This object might be mutable, @c const, @c volatile, or
0367                 <c>const volatile</c> depending on the cv-qualifier of the
0368                 enclosing function (volatile public functions will check
0369                 volatile class invariants, see
0370                 @RefSect{extras.volatile_public_functions,
0371                 Volatile Public Functions}).
0372 
0373     @tparam Class   The type of the class containing the virtual public function
0374                     declaring the contract.
0375                     (Usually this template parameter is automatically deduced by
0376                     C++ and it does not need to be explicitly specified by
0377                     programmers.)
0378     
0379     @return The result of this function must be assigned to a variable of type
0380             @RefClass{boost::contract::check} declared explicitly (i.e., without
0381             using C++11 @c auto declarations) and locally just before the code
0382             of the public function body (otherwise this library will generate a
0383             run-time error, see
0384             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0385     */
0386     template<class Class>
0387     specify_precondition_old_postcondition_except<> public_function(
0388             virtual_* v, Class* obj);
0389     
0390     /**
0391     Program contracts for non-void virtual public functions that do not
0392     override.
0393 
0394     This is used to specify preconditions, postconditions, exception guarantees,
0395     old value copies at body, and check class invariants for public functions
0396     that are virtual, do not override, and do not return @c void:
0397     
0398     @code
0399     class u {
0400         friend class boost::contract::access;
0401 
0402         void invariant() const { // Optional (as for static and volatile).
0403             BOOST_CONTRACT_ASSERT(...);
0404             ...
0405         }
0406 
0407     public:
0408         t f(..., boost::contract::virtual_* v = 0) {
0409             t result;
0410             boost::contract::old_ptr<old_type> old_var;
0411             boost::contract::check c = boost::contract::public_function(
0412                     v, result, this)
0413                 .precondition([&] { // Optional.
0414                     BOOST_CONTRACT_ASSERT(...);
0415                     ...
0416                 })
0417                 .old([&] { // Optional.
0418                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
0419                     ...
0420                 })
0421                 .postcondition([&] (t const& result) { // Optional.
0422                     BOOST_CONTRACT_ASSERT(...);
0423                     ...
0424                 })
0425                 .except([&] { // Optional.
0426                     BOOST_CONTRACT_ASSERT(...);
0427                     ...
0428                 })
0429             ;
0430 
0431             ... // Function body (use `return result = return_expr`).
0432         }
0433         
0434         ...
0435     };
0436     @endcode
0437 
0438     A virtual public function should always call
0439     @RefFunc{boost::contract::public_function} otherwise this library will not
0440     be able to correctly use it for subcontracting.
0441 
0442     @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
0443     
0444     @param v    The trailing parameter of type
0445                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
0446                 @c 0 from the enclosing virtual public function.
0447     @param r    A reference to the return value of the enclosing virtual public
0448                 function declaring the contract.
0449                 This is usually a local variable declared by the enclosing
0450                 virtual public function just before the contract, but
0451                 programmers must set it to the actual value being returned by
0452                 the function at each @c return statement.
0453     @param obj  The object @c this from the scope of the enclosing virtual
0454                 public function declaring the contract.
0455                 This object might be mutable, @c const, @c volatile, or
0456                 <c>const volatile</c> depending on the cv-qualifier of the
0457                 enclosing function (volatile public functions will check
0458                 volatile class invariants, see
0459                 @RefSect{extras.volatile_public_functions,
0460                 Volatile Public Functions}).
0461     
0462     @tparam VirtualResult   This type must be the same as, or compatible with,
0463                             the return type of the enclosing virtual public
0464                             function declaring the contract (this library might
0465                             not be able to generate a compile-time error if
0466                             these types mismatch, but in general that will cause
0467                             run-time errors or undefined behaviour).
0468                             Alternatively,
0469                             <c>boost::optional<<i>return-type</i>></c> can also
0470                             be used (see
0471                             @RefSect{advanced.optional_return_values,
0472                             Optional Return Values}).
0473                             (Usually this template parameter is automatically
0474                             deduced by C++ and it does not need to be explicitly
0475                             specified by programmers.)
0476     @tparam Class   The type of the class containing the virtual public function
0477                     declaring the contract.
0478                     (Usually this template parameter is automatically deduced by
0479                     C++ and it does not need to be explicitly specified by
0480                     programmers.)
0481     
0482     @return The result of this function must be assigned to a variable of type
0483             @RefClass{boost::contract::check} declared explicitly (i.e., without
0484             using C++11 @c auto declarations) and locally just before the code
0485             of the public function body (otherwise this library will generate a
0486             run-time error, see
0487             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0488     */
0489     template<typename VirtualResult, class Class>
0490     specify_precondition_old_postcondition_except<VirtualResult>
0491     public_function(virtual_* v, VirtualResult& r, Class* obj);
0492 #else
0493     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
0494             /* has_virtual_result = */ 0)
0495     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
0496             /* has_virtual_result = */ 1)
0497 #endif
0498 
0499 /** @cond */
0500 
0501 // For non-static, virtual, and overriding public functions (PRIVATE macro).
0502 #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
0503         z, arity, arity_compl, has_virtual_result) \
0504     BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
0505         arity, /* is_friend = */ 0, has_virtual_result, \
0506         Override, VirtualResult, F, Class, Args, \
0507         v, r, /* f */ BOOST_PP_EMPTY(), obj, args \
0508     ) { \
0509         BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
0510             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
0511                 /* assert not strictly necessary as compilation will fail */ \
0512                 /* anyways, but helps limiting cryptic compiler's errors */ \
0513                 BOOST_STATIC_ASSERT_MSG( \
0514                     /* -2 for both `this` and `virtual_*` extra parameters */ \
0515                     ( \
0516                         boost::function_types::function_arity<F>::value - 2 \
0517                     == \
0518                         BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args) \
0519                     ), \
0520                     "missing one or more arguments for specified function" \
0521                 ); \
0522             } \
0523             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
0524                 /* assert consistency of F's result type and VirtualResult */ \
0525                 BOOST_PP_IIF(has_virtual_result, \
0526                     BOOST_STATIC_ASSERT_MSG \
0527                 , \
0528                     BOOST_PP_TUPLE_EAT(2) \
0529                 )( \
0530                     (boost::is_same< \
0531                         typename boost::remove_reference<typename boost:: \
0532                                 function_types::result_type<F>::type>::type, \
0533                         typename boost::contract::detail:: \
0534                                 remove_value_reference_if_optional< \
0535                             VirtualResult \
0536                         >::type \
0537                     >::value), \
0538                     "mismatching result type for specified function" \
0539                 ); \
0540             } \
0541             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
0542                 /* assert this so lib can check and enforce override */ \
0543                 BOOST_STATIC_ASSERT_MSG( \
0544                     boost::contract::access::has_base_types<Class>::value, \
0545                     "enclosing class missing 'base-types' typedef" \
0546                 ); \
0547             } \
0548             return (specify_precondition_old_postcondition_except< \
0549                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
0550                 new boost::contract::detail::public_function< \
0551                     Override, \
0552                     BOOST_PP_IIF(has_virtual_result, \
0553                         VirtualResult \
0554                     , \
0555                         boost::contract::detail::none \
0556                     ), \
0557                     F, \
0558                     Class \
0559                     BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
0560                     BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \
0561                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
0562                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
0563                             boost::contract::detail::none) \
0564                 >( \
0565                     v, \
0566                     obj, \
0567                     BOOST_PP_IIF(has_virtual_result, \
0568                         r \
0569                     , \
0570                         boost::contract::detail::none::value() \
0571                     ) \
0572                     BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
0573                     BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, args) \
0574                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
0575                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
0576                             boost::contract::detail::none::value()) \
0577                 ) \
0578             )); \
0579         , \
0580             return specify_precondition_old_postcondition_except< \
0581                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
0582         ) \
0583     }
0584 
0585 /** @endcond */
0586 
0587 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0588     /**
0589     Program contracts for void public functions overrides (virtual or not).
0590 
0591     This is used to specify preconditions, postconditions, exception guarantees,
0592     old value copies at body, and check class invariants for public function
0593     overrides (virtual or not) that return @c void:
0594     
0595     @code
0596     class u
0597         #define BASES private boost::contract::constructor_precondition<u>, \
0598                 public b, private w
0599         : BASES
0600     {
0601         friend class boost::contract::access;
0602 
0603         typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
0604         #undef BASES
0605 
0606         void invariant() const { // Optional (as for static and volatile).
0607             BOOST_CONTRACT_ASSERT(...);
0608             ...
0609         }
0610 
0611         BOOST_CONTRACT_OVERRIDES(f)
0612 
0613     public:
0614         // Override from `b::f`.
0615         void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
0616             boost::contract::old_ptr<old_type> old_var;
0617             boost::contract::check c = boost::contract::public_function<
0618                     override_f>(v, &u::f, this, a_1, ..., a_n)
0619                 .precondition([&] { // Optional.
0620                     BOOST_CONTRACT_ASSERT(...);
0621                     ...
0622                 })
0623                 .old([&] { // Optional.
0624                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
0625                     ...
0626                 })
0627                 .postcondition([&] { // Optional.
0628                     BOOST_CONTRACT_ASSERT(...);
0629                     ...
0630                 })
0631                 .except([&] { // Optional.
0632                     BOOST_CONTRACT_ASSERT(...);
0633                     ...
0634                 })
0635             ;
0636 
0637             ... // Function body.
0638         }
0639         
0640         ...
0641     };
0642     @endcode
0643 
0644     A public function override should always call
0645     @RefFunc{boost::contract::public_function} otherwise this library will not
0646     be able to correctly use it for subcontracting.
0647 
0648     @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
0649             Public Function Overrides}
0650     
0651     @param v    The trailing parameter of type
0652                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
0653                 @c 0 from the enclosing public function override.
0654     @param f    A pointer to the enclosing public function override declaring
0655                 the contract (but see @RefSect{advanced.function_overloads,
0656                 Function Overloads}).
0657     @param obj  The object @c this from the scope of the enclosing public
0658                 function override declaring the contract.
0659                 This object might be mutable, @c const, @c volatile, or
0660                 <c>const volatile</c> depending on the cv-qualifier of the
0661                 enclosing function (volatile public functions will check
0662                 volatile class invariants, see
0663                 @RefSect{extras.volatile_public_functions,
0664                 Volatile Public Functions}).
0665     @param args All arguments passed to the enclosing public function override
0666                 declaring the contract (by reference and in the order they
0667                 appear in the enclosing function declaration), but excluding the
0668                 trailing argument @c v.
0669 
0670     @tparam Override    The type trait <c>override_<i>function-name</i></c>
0671                         declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
0672                         related macros.
0673                         This template parameter must be explicitly specified
0674                         (because there is no function argument from which it can
0675                         be automatically deduced by C++).
0676     @tparam F   The function pointer type of the enclosing public function
0677                 override declaring the contract.
0678                 (Usually this template parameter is automatically deduced by
0679                 C++ and it does not need to be explicitly specified by
0680                 programmers.)
0681     @tparam Class   The type of the class containing the virtual public function
0682                     declaring the contract.
0683                     (Usually this template parameter is automatically deduced by
0684                     C++ and it does not need to be explicitly specified by
0685                     programmers.)
0686     @tparam Args    The types of all parameters passed to the enclosing public
0687                     function override declaring the contract, but excluding the
0688                     trailing parameter type <c>boost::contract::virtual_*</c>.
0689                     On compilers that do not support variadic templates, this
0690                     library internally implements this function using
0691                     preprocessor meta-programming (in this case, the maximum
0692                     number of supported arguments is defined by
0693                     @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
0694                     (Usually these template parameters are automatically deduced
0695                     by C++ and they do not need to be explicitly specified by
0696                     programmers.)
0697 
0698     @return The result of this function must be assigned to a variable of type
0699             @RefClass{boost::contract::check} declared explicitly (i.e., without
0700             using C++11 @c auto declarations) and locally just before the code
0701             of the public function body (otherwise this library will generate a
0702             run-time error, see
0703             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0704     */
0705     template<class Override, typename F, class Class, typename... Args>
0706     specify_precondition_old_postcondition_except<> public_function(
0707             virtual_* v, F f, Class* obj, Args&... args);
0708 
0709     /**
0710     Program contracts for non-void public functions overrides (virtual or not).
0711 
0712     This is used to specify preconditions, postconditions, exception guarantees,
0713     old value copies at body, and check class invariants for public function
0714     overrides (virtual or not) that do not return @c void:
0715     
0716     @code
0717     class u
0718         #define BASES private boost::contract::constructor_precondition<u>, \
0719                 public b, private w
0720         : BASES
0721     {
0722         friend class boost::contract::access;
0723 
0724         typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
0725         #undef BASES
0726 
0727         void invariant() const { // Optional (as for static and volatile).
0728             BOOST_CONTRACT_ASSERT(...);
0729             ...
0730         }
0731 
0732         BOOST_CONTRACT_OVERRIDES(f)
0733 
0734     public:
0735         // Override from `b::f`.
0736         t f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
0737             t result;
0738             boost::contract::old_ptr<old_type> old_var;
0739             boost::contract::check c = boost::contract::public_function<
0740                     override_f>(v, result, &u::f, this, a_1, ..., a_n)
0741                 .precondition([&] { // Optional.
0742                     BOOST_CONTRACT_ASSERT(...);
0743                     ...
0744                 })
0745                 .old([&] { // Optional.
0746                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
0747                     ...
0748                 })
0749                 .postcondition([&] (t const& result) { // Optional.
0750                     BOOST_CONTRACT_ASSERT(...);
0751                     ...
0752                 })
0753                 .except([&] { // Optional.
0754                     BOOST_CONTRACT_ASSERT(...);
0755                     ...
0756                 })
0757             ;
0758 
0759             ... // Function body (use `return result = return_expr`).
0760         }
0761         
0762         ...
0763     };
0764     @endcode
0765 
0766     A public function override should always call
0767     @RefFunc{boost::contract::public_function} otherwise this library will not
0768     be able to correctly use it for subcontracting.
0769 
0770     @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
0771             Public Function Overrides}
0772     
0773     @param v    The trailing parameter of type
0774                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
0775                 @c 0 from the enclosing public function override.
0776     @param r    A reference to the return value of the enclosing public function
0777                 override declaring the contract.
0778                 This is usually a local variable declared by the enclosing
0779                 public function override just before the contract, but
0780                 programmers must set it to the actual value being returned by
0781                 the function at each @c return statement.
0782     @param f    A pointer to the enclosing public function override declaring
0783                 the contract (but see @RefSect{advanced.function_overloads,
0784                 Function Overloads}).
0785     @param obj  The object @c this from the scope of the enclosing public
0786                 function override declaring the contract.
0787                 This object might be mutable, @c const, @c volatile, or
0788                 <c>const volatile</c> depending on the cv-qualifier of the
0789                 enclosing function (volatile public functions will check
0790                 volatile class invariants, see
0791                 @RefSect{extras.volatile_public_functions,
0792                 Volatile Public Functions}).
0793     @param args All arguments passed to the enclosing public function override
0794                 declaring the contract (by reference and in the order they
0795                 appear in the enclosing function declaration), but excluding the
0796                 trailing argument @c v.
0797 
0798     @tparam Override    The type trait <c>override_<i>function-name</i></c>
0799                         declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
0800                         related macros.
0801                         This template parameter must be explicitly specified
0802                         (because there is no function argument from which it can
0803                         be automatically deduced by C++).
0804     @tparam VirtualResult   This type must be the same as, or compatible with,
0805                             the return type of the enclosing public function
0806                             override declaring the contract (this library might
0807                             not be able to generate a compile-time error if
0808                             these types mismatch, but in general that will cause
0809                             run-time errors or undefined behaviour).
0810                             Alternatively,
0811                             <c>boost::optional<<i>return-type</i>></c> can also
0812                             be used (see
0813                             @RefSect{advanced.optional_return_values,
0814                             Optional Return Values}).
0815                             (Usually this template parameter is automatically
0816                             deduced by C++ and it does not need to be explicitly
0817                             specified by programmers.)
0818     @tparam F   The function pointer type of the enclosing public function
0819                 override declaring the contract.
0820                 (Usually this template parameter is automatically deduced by
0821                 C++ and it does not need to be explicitly specified by
0822                 programmers.)
0823     @tparam Class   The type of the class containing the virtual public function
0824                     declaring the contract.
0825                     (Usually this template parameter is automatically deduced by
0826                     C++ and it does not need to be explicitly specified by
0827                     programmers.)
0828     @tparam Args    The types of all parameters passed to the enclosing public
0829                     function override declaring the contract, but excluding the
0830                     trailing parameter type <c>boost::contract::virtual_*</c>.
0831                     On compilers that do not support variadic templates, this
0832                     library internally implements this function using
0833                     preprocessor meta-programming (in this case, the maximum
0834                     number of supported arguments is defined by
0835                     @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
0836                     (Usually these template parameters are automatically deduced
0837                     by C++ and they do not need to be explicitly specified by
0838                     programmers.)
0839 
0840     @return The result of this function must be assigned to a variable of type
0841             @RefClass{boost::contract::check} declared explicitly (i.e., without
0842             using C++11 @c auto declarations) and locally just before the code
0843             of the public function body (otherwise this library will generate a
0844             run-time error, see
0845             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0846     */
0847     template<class Override, typename VirtualResult, typename F, class Class,
0848             typename... Args>
0849     specify_precondition_old_postcondition_except<VirtualResult>
0850     public_function(virtual_* v, VirtualResult& r, F f, Class* obj,
0851             Args&... args);
0852 
0853 #elif BOOST_CONTRACT_DETAIL_TVARIADIC
0854     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
0855             /* arity_compl = */ ~, /* has_virtual_result = */ 0)
0856     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
0857             /* arity_compl = */ ~, /* has_virtual_result = */ 1)
0858 
0859 #else
0860     /* PRIVATE */
0861 
0862     #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_( \
0863             z, arity, unused) \
0864         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, arity, \
0865                 BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), ~)
0866     
0867     #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \
0868             arity, arity_compl, unused) \
0869         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
0870                 arity, arity_compl, /* has_virtual_result = */ 0) \
0871         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
0872                 arity, arity_compl, /* has_virtual_result = */ 1)
0873 
0874     /* CODE */
0875 
0876     BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
0877             BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_, ~)
0878 #endif
0879 
0880 } } // namespace
0881 
0882 #endif // #include guard
0883