Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:25

0001 
0002 #ifndef BOOST_CONTRACT_SPECIFY_HPP_
0003 #define BOOST_CONTRACT_SPECIFY_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 Specify preconditions, old values copied at body, postconditions, and exception
0012 guarantees
0013 
0014 Preconditions, old values copied at body, postconditions, and exception
0015 guarantees are all optionals but, when they are specified, they need to be
0016 specified in that order.
0017 */
0018 
0019 #include <boost/contract/core/config.hpp>
0020 #include <boost/contract/detail/decl.hpp>
0021 #if     !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
0022         defined(BOOST_CONTRACT_STATIC_LINK)
0023     #include <boost/contract/detail/condition/cond_base.hpp>
0024     #include <boost/contract/detail/condition/cond_post.hpp>
0025     #include <boost/contract/detail/auto_ptr.hpp>
0026     #include <boost/contract/detail/none.hpp>
0027 #endif
0028 #if     !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
0029         !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
0030         !defined(BOOST_CONTRACT_NO_EXCEPTS)
0031     #include <boost/contract/detail/debug.hpp>
0032 #endif
0033 #include <boost/config.hpp>
0034 
0035 // NOTE: No inheritance for faster run-times (macros to avoid duplicated code).
0036 
0037 /* PRIVATE */
0038 
0039 /* @cond */
0040 
0041 // NOTE: Private copy ops below will force compile-time error is `auto c = ...`
0042 // is used instead of `check c = ...` but only up to C++17. C++17 strong copy
0043 // elision on function return values prevents this lib from generating a
0044 // compile-time error in those cases, but the lib will still generate a run-time
0045 // error according with ON_MISSING_CHECK_DECL. Furthermore, on some C++98
0046 // compilers, this private copy ctor gives a warning (because of lack of copy
0047 // optimization on those compilers), this warning can be ignored.
0048 #if     !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
0049         defined(BOOST_CONTRACT_STATIC_LINK)
0050     #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \
0051         private: \
0052             boost::contract::detail::auto_ptr<cond_type > cond_; \
0053             explicit class_type(cond_type* cond) : cond_(cond) {} \
0054             class_type(class_type const& other) : cond_(other.cond_) {} \
0055             class_type& operator=(class_type const& other) { \
0056                 cond_ = other.cond_; \
0057                 return *this; \
0058             }
0059     
0060     #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ cond_.release()
0061 #else
0062     #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \
0063         private: \
0064             class_type() {} \
0065             class_type(class_type const&) {} \
0066             class_type& operator=(class_type const&) { return *this; }
0067 
0068     #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ /* nothing */
0069 #endif
0070 
0071 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
0072     #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \
0073         BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
0074         cond_->set_pre(f); \
0075         return specify_old_postcondition_except<VirtualResult>( \
0076                 BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0077 #else
0078     #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \
0079         return specify_old_postcondition_except<VirtualResult>( \
0080                 BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0081 #endif
0082         
0083 #ifndef BOOST_CONTRACT_NO_OLDS
0084     #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \
0085         BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
0086         cond_->set_old(f); \
0087         return specify_postcondition_except<VirtualResult>( \
0088                 BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0089 #else
0090     #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \
0091         return specify_postcondition_except<VirtualResult>( \
0092                 BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0093 #endif
0094             
0095 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
0096     #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \
0097         BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
0098         cond_->set_post(f); \
0099         return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0100 #else
0101     #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \
0102         return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0103 #endif
0104         
0105 #ifndef BOOST_CONTRACT_NO_EXCEPTS
0106     #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \
0107         BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
0108         cond_->set_except(f); \
0109         return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0110 #else
0111     #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \
0112         return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_);
0113 #endif
0114 
0115 /* @endcond */
0116 
0117 /* CODE */
0118 
0119 namespace boost {
0120     namespace contract {
0121         class virtual_;
0122         
0123         template<typename VR>
0124         class specify_precondition_old_postcondition_except;
0125         
0126         template<typename VR>
0127         class specify_old_postcondition_except;
0128         
0129         template<typename VR>
0130         class specify_postcondition_except;
0131         
0132         class specify_except;
0133     }
0134 }
0135 
0136 namespace boost { namespace contract {
0137 
0138 /**
0139 Used to prevent setting other contract conditions after exception guarantees.
0140 
0141 This class has no member function so it is used to prevent specifying additional
0142 functors to check any other contract.
0143 This object is internally constructed by the library when users specify
0144 contracts calling @RefFunc{boost::contract::function} and similar functions
0145 (that is why this class does not have a public constructor).
0146 
0147 @see @RefSect{tutorial, Tutorial}
0148 */
0149 class specify_nothing { // Privately copyable (as *).
0150 public:
0151     /**
0152     Destruct this object.
0153 
0154     @b Throws:  This is declared @c noexcept(false) since C++11 to allow users
0155                 to program failure handlers that throw exceptions on contract
0156                 assertion failures (not the default, see
0157                 @RefSect{advanced.throw_on_failures__and__noexcept__,
0158                 Throw on Failure}).
0159     */
0160     ~specify_nothing() BOOST_NOEXCEPT_IF(false) {}
0161     
0162     // No set member function here.
0163 
0164 /** @cond */
0165 private:
0166     BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_nothing,
0167             boost::contract::detail::cond_base)
0168 
0169     // Friends (used to limit library's public API).
0170 
0171     friend class check;
0172 
0173     template<typename VR>
0174     friend class specify_precondition_old_postcondition_except;
0175     
0176     template<typename VR>
0177     friend class specify_old_postcondition_except;
0178 
0179     template<typename VR>
0180     friend class specify_postcondition_except;
0181 
0182     friend class specify_except;
0183 /** @endcond */
0184 };
0185 
0186 /**
0187 Allow to specify exception guarantees.
0188 
0189 Allow to specify the functor this library will call to check exception
0190 guarantees.
0191 This object is internally constructed by the library when users specify
0192 contracts calling @RefFunc{boost::contract::function} and similar functions
0193 (that is why this class does not have a public constructor).
0194 
0195 @see @RefSect{tutorial.exception_guarantees, Exception Guarantees}
0196 */
0197 class specify_except { // Privately copyable (as *).
0198 public:
0199     /**
0200     Destruct this object.
0201 
0202     @b Throws:  This is declared @c noexcept(false) since C++11 to allow users
0203                 to program failure handlers that throw exceptions on contract
0204                 assertion failures (not the default, see
0205                 @RefSect{advanced.throw_on_failures__and__noexcept__,
0206                 Throw on Failure}).
0207     */
0208     ~specify_except() BOOST_NOEXCEPT_IF(false) {}
0209 
0210     /**
0211     Allow to specify exception guarantees.
0212 
0213     @param f    Nullary functor called by this library to check exception
0214                 guarantees @c f().
0215                 Assertions within this functor are usually programmed using
0216                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0217                 call to this functor indicates a contract assertion failure (and
0218                 will result in this library calling
0219                 @RefFunc{boost::contract::except_failure}).
0220                 This functor should capture variables by (constant) references
0221                 (to access the values they will have at function exit).
0222 
0223     @return After exception guarantees have been specified, the object returned
0224             by this function does not allow to specify any additional contract.
0225     */
0226     template<typename F>
0227     specify_nothing except(
0228         F const&
0229         #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \
0230                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0231             f
0232         #endif // Else, no name (avoid unused param warning).
0233     ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ }
0234 
0235 /** @cond */
0236 private:
0237     BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_except,
0238             boost::contract::detail::cond_base)
0239 
0240     // Friends (used to limit library's public API).
0241 
0242     friend class check;
0243 
0244     template<typename VR>
0245     friend class specify_precondition_old_postcondition_except;
0246     
0247     template<typename VR>
0248     friend class specify_old_postcondition_except;
0249     
0250     template<typename VR>
0251     friend class specify_postcondition_except;
0252 /** @endcond */
0253 };
0254 
0255 /**
0256 Allow to specify postconditions or exception guarantees.
0257 
0258 Allow to specify functors this library will call to check postconditions or
0259 exception guarantees.
0260 This object is internally constructed by the library when users specify
0261 contracts calling @RefFunc{boost::contract::function} and similar functions
0262 (that is why this class does not have a public constructor).
0263 
0264 @see    @RefSect{tutorial.postconditions, Postconditions},
0265         @RefSect{tutorial.exception_guarantees, Exception Guarantees}
0266 
0267 @tparam VirtualResult   Return type of the enclosing function declaring the
0268                         contract if that is either a virtual or an
0269                         overriding public function, otherwise this is always
0270                         @c void.
0271                         (Usually this template parameter is automatically
0272                         deduced by C++ and it does not need to be explicitly
0273                         specified by programmers.)
0274 */
0275 template<typename VirtualResult = void>
0276 class specify_postcondition_except { // Privately copyable (as *).
0277 public:
0278     /**
0279     Destruct this object.
0280 
0281     @b Throws:  This is declared @c noexcept(false) since C++11 to allow users
0282                 to program failure handlers that throw exceptions on contract
0283                 assertion failures (not the default, see
0284                 @RefSect{advanced.throw_on_failures__and__noexcept__,
0285                 Throw on Failure}).
0286     */
0287     ~specify_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
0288 
0289     /**
0290     Allow to specify postconditions.
0291 
0292     @param f    Functor called by this library to check postconditions
0293                 @c f() or @c f(result).
0294                 Assertions within this functor are usually programmed using
0295                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0296                 call to this functor indicates a contract assertion failure (and
0297                 will result in this library calling
0298                 @RefFunc{boost::contract::postcondition_failure}).
0299                 This functor should capture variables by (constant) references
0300                 (to access the values they will have at function exit).
0301                 This functor must be a nullary functor @c f() if
0302                 @c VirtualResult is @c void, otherwise it must be a unary
0303                 functor @c f(result) accepting the return value @c result as a
0304                 parameter of type <c>VirtualResult const&</c> (to avoid extra
0305                 copies of the return value, or of type @c VirtualResult or
0306                 <c>VirtualResult const</c> if extra copies of the return value
0307                 are irrelevant).
0308 
0309     @return After postconditions have been specified, the object returned by
0310             this function allows to optionally specify exception guarantees.
0311     */
0312     template<typename F>
0313     specify_except postcondition(
0314         F const&
0315         #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
0316                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0317             f
0318         #endif // Else, no name (avoid unused param warning).
0319     ) {
0320         BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
0321     }
0322     
0323     /**
0324     Allow to specify exception guarantees.
0325 
0326     @param f    Nullary functor called by this library to check exception
0327                 guarantees @c f().
0328                 Assertions within this functor are usually programmed using
0329                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0330                 call to this functor indicates a contract assertion failure (and
0331                 will result in this library calling
0332                 @RefFunc{boost::contract::except_failure}).
0333                 This functor should capture variables by (constant) references
0334                 (to access the values they will have at function exit).
0335 
0336     @return After exception guarantees have been specified, the object returned
0337             by this function does not allow to specify any additional contract.
0338     */
0339     template<typename F>
0340     specify_nothing except(
0341         F const&
0342         #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \
0343                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0344             f
0345         #endif // Else, no name (avoid unused param warning).
0346     ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ }
0347 
0348 /** @cond */
0349 private:
0350     BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
0351         specify_postcondition_except,
0352         boost::contract::detail::cond_post<typename
0353                 boost::contract::detail::none_if_void<VirtualResult>::type>
0354     )
0355 
0356     // Friends (used to limit library's public API).
0357 
0358     friend class check;
0359     friend class specify_precondition_old_postcondition_except<VirtualResult>;
0360     friend class specify_old_postcondition_except<VirtualResult>;
0361 /** @endcond */
0362 };
0363 
0364 /**
0365 Allow to specify old values copied at body, postconditions, and exception
0366 guarantees.
0367 
0368 Allow to specify functors this library will call to copy old values at body, 
0369 check postconditions, and check exception guarantees.
0370 This object is internally constructed by the library when users specify
0371 contracts calling @RefFunc{boost::contract::function} and similar functions
0372 (that is why this class does not have a public constructor).
0373 
0374 @see    @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body},
0375         @RefSect{tutorial.postconditions, Postconditions},
0376         @RefSect{tutorial.exception_guarantees, Exception Guarantees}
0377 
0378 @tparam VirtualResult   Return type of the enclosing function declaring the
0379                         contract if that is either a virtual or an
0380                         overriding public function, otherwise this is always
0381                         @c void.
0382                         (Usually this template parameter is automatically
0383                         deduced by C++ and it does not need to be explicitly
0384                         specified by programmers.)
0385 */
0386 template<typename VirtualResult = void>
0387 class specify_old_postcondition_except { // Privately copyable (as *).
0388 public:
0389     /**
0390     Destruct this object.
0391 
0392     @b Throws:  This is declared @c noexcept(false) since C++11 to allow users
0393                 to program failure handlers that throw exceptions on contract
0394                 assertion failures (not the default, see
0395                 @RefSect{advanced.throw_on_failures__and__noexcept__,
0396                 Throw on Failure}).
0397     */
0398     ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
0399     
0400     /**
0401     Allow to specify old values copied at body.
0402 
0403     It should often be sufficient to initialize old value pointers as soon as
0404     they are declared, without using this function (see
0405     @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}).
0406 
0407     @param f    Nullary functor called by this library @c f() to assign old
0408                 value copies just before the body is executed but after entry
0409                 invariants (when they apply) and preconditions are checked.
0410                 Old value pointers within this functor call are usually assigned
0411                 using @RefMacro{BOOST_CONTRACT_OLDOF}.
0412                 Any exception thrown by a call to this functor will result in
0413                 this library calling @RefFunc{boost::contract::old_failure}
0414                 (because old values could not be copied to check postconditions
0415                 and exception guarantees).
0416                 This functor should capture old value pointers by references so
0417                 they can be assigned (all other variables needed to evaluate old
0418                 value expressions can be captured by (constant) value, or better
0419                 by (constant) reference to avoid extra copies).
0420 
0421     @return After old values copied at body have been specified, the object
0422             returned by this function allows to optionally specify
0423             postconditions and exception guarantees.
0424     */
0425     template<typename F>
0426     specify_postcondition_except<VirtualResult> old(
0427         F const&
0428         #if !defined(BOOST_CONTRACT_NO_OLDS) || \
0429                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0430             f
0431         #endif // Else, no name (avoid unused param warning).
0432     ) {
0433         BOOST_CONTRACT_SPECIFY_OLD_IMPL_
0434     }
0435 
0436     /**
0437     Allow to specify postconditions.
0438 
0439     @param f    Functor called by this library to check postconditions
0440                 @c f() or @c f(result).
0441                 Assertions within this functor are usually programmed using
0442                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0443                 call to this functor indicates a contract assertion failure (and
0444                 will result in this library calling
0445                 @RefFunc{boost::contract::postcondition_failure}).
0446                 This functor should capture variables by (constant) references
0447                 (to access the values they will have at function exit).
0448                 This functor must be a nullary functor @c f() if
0449                 @c VirtualResult is @c void, otherwise it must be a unary
0450                 functor @c f(result) accepting the return value @c result as a
0451                 parameter of type <c>VirtualResult const&</c> (to avoid extra
0452                 copies of the return value, or of type @c VirtualResult or
0453                 <c>VirtualResult const</c> if extra copies of the return value
0454                 are irrelevant).
0455 
0456     @return After postconditions have been specified, the object returned by
0457             this function allows to optionally specify exception guarantees.
0458     */
0459     template<typename F>
0460     specify_except postcondition(
0461         F const&
0462         #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
0463                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0464             f
0465         #endif // Else, no name (avoid unused param warning).
0466     ) {
0467         BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
0468     }
0469     
0470     /**
0471     Allow to specify exception guarantees.
0472 
0473     @param f    Nullary functor called by this library to check exception
0474                 guarantees @c f().
0475                 Assertions within this functor are usually programmed using
0476                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0477                 call to this functor indicates a contract assertion failure (and
0478                 will result in this library calling
0479                 @RefFunc{boost::contract::except_failure}).
0480                 This functor should capture variables by (constant) references
0481                 (to access the values they will have at function exit).
0482 
0483     @return After exception guarantees have been specified, the object returned
0484             by this function does not allow to specify any additional contract.
0485     */
0486     template<typename F>
0487     specify_nothing except(
0488         F const&
0489         #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \
0490                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0491             f
0492         #endif // Else, no name (avoid unused param warning).
0493     ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ }
0494 
0495 /** @cond */
0496 private:
0497     BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
0498         specify_old_postcondition_except,
0499         boost::contract::detail::cond_post<typename
0500                 boost::contract::detail::none_if_void<VirtualResult>::type>
0501     )
0502 
0503     // Friends (used to limit library's public API).
0504 
0505     friend class check;
0506     friend class specify_precondition_old_postcondition_except<VirtualResult>;
0507 
0508     template<class C>
0509     friend specify_old_postcondition_except<> constructor(C*);
0510 
0511     template<class C>
0512     friend specify_old_postcondition_except<> destructor(C*);
0513 /** @endcond */
0514 };
0515 
0516 /**
0517 Allow to specify preconditions, old values copied at body, postconditions, and
0518 exception guarantees.
0519 
0520 Allow to specify functors this library will call to check preconditions, copy
0521 old values at body, check postconditions, and check exception guarantees.
0522 This object is internally constructed by the library when users specify
0523 contracts calling @RefFunc{boost::contract::function} and similar functions
0524 (that is why this class does not have a public constructor).
0525 
0526 @see    @RefSect{tutorial.preconditions, Preconditions},
0527         @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body},
0528         @RefSect{tutorial.postconditions, Postconditions},
0529         @RefSect{tutorial.exception_guarantees, Exception Guarantees}
0530 
0531 @tparam VirtualResult   Return type of the enclosing function declaring the
0532                         contract if that is either a virtual or an
0533                         overriding public function, otherwise this is always
0534                         @c void.
0535                         (Usually this template parameter is automatically
0536                         deduced by C++ and it does not need to be explicitly
0537                         specified by programmers.)
0538 */
0539 template<
0540     typename VirtualResult /* = void (already in fwd decl from decl.hpp) */
0541     #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0542         = void
0543     #endif
0544 >
0545 class specify_precondition_old_postcondition_except { // Priv. copyable (as *).
0546 public:
0547     /**
0548     Destruct this object.
0549 
0550     @b Throws:  This is declared @c noexcept(false) since C++11 to allow users
0551                 to program failure handlers that throw exceptions on contract
0552                 assertion failures (not the default, see
0553                 @RefSect{advanced.throw_on_failures__and__noexcept__,
0554                 Throw on Failure}).
0555     */
0556     ~specify_precondition_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {}
0557     
0558     /**
0559     Allow to specify preconditions.
0560 
0561     @param f    Nullary functor called by this library to check preconditions
0562                 @c f().
0563                 Assertions within this functor are usually programmed using
0564                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0565                 call to this functor indicates a contract assertion failure (and
0566                 will result in this library calling
0567                 @RefFunc{boost::contract::precondition_failure}).
0568                 This functor should capture variables by (constant) value, or
0569                 better by (constant) reference (to avoid extra copies).
0570 
0571     @return After preconditions have been specified, the object returned by this
0572             function allows to optionally specify old values copied at body,
0573             postconditions, and exception guarantees.
0574     */
0575     template<typename F>
0576     specify_old_postcondition_except<VirtualResult> precondition(
0577         F const&
0578         #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
0579                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0580             f
0581         #endif // Else, no name (avoid unused param warning).
0582     ) {
0583         BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_
0584     }
0585 
0586     /**
0587     Allow to specify old values copied at body.
0588 
0589     It should often be sufficient to initialize old value pointers as soon as
0590     they are declared, without using this function (see
0591     @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}).
0592 
0593     @param f    Nullary functor called by this library @c f() to assign old
0594                 value copies just before the body is executed but after entry
0595                 invariants (when they apply) and preconditions are checked.
0596                 Old value pointers within this functor call are usually assigned
0597                 using @RefMacro{BOOST_CONTRACT_OLDOF}.
0598                 Any exception thrown by a call to this functor will result in
0599                 this library calling @RefFunc{boost::contract::old_failure}
0600                 (because old values could not be copied to check postconditions
0601                 and exception guarantees).
0602                 This functor should capture old value pointers by references so
0603                 they can be assigned (all other variables needed to evaluate old
0604                 value expressions can be captured by (constant) value, or better
0605                 by (constant) reference to avoid extra copies).
0606 
0607     @return After old values copied at body have been specified, the object
0608             returned by this functions allows to optionally specify
0609             postconditions and exception guarantees.
0610     */
0611     template<typename F>
0612     specify_postcondition_except<VirtualResult> old(
0613         F const&
0614         #if !defined(BOOST_CONTRACT_NO_OLDS) || \
0615                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0616             f
0617         #endif // Else, no name (avoid unused param warning).
0618     ) {
0619         BOOST_CONTRACT_SPECIFY_OLD_IMPL_
0620     }
0621 
0622     /**
0623     Allow to specify postconditions.
0624 
0625     @param f    Functor called by this library to check postconditions
0626                 @c f() or @c f(result).
0627                 Assertions within this functor are usually programmed using
0628                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0629                 call to this functor indicates a contract assertion failure (and
0630                 will result in this library calling
0631                 @RefFunc{boost::contract::postcondition_failure}).
0632                 This functor should capture variables by (constant) references
0633                 (to access the values they will have at function exit).
0634                 This functor must be a nullary functor @c f() if
0635                 @c VirtualResult is @c void, otherwise it must be a unary
0636                 functor @c f(result) accepting the return value @c result as a
0637                 parameter of type <c>VirtualResult const&</c> (to avoid extra
0638                 copies of the return value, or of type @c VirtualResult or
0639                 <c>VirtualResult const</c> if extra copies of the return value
0640                 are irrelevant).
0641 
0642     @return After postconditions have been specified, the object returned by
0643             this function allows to optionally specify exception guarantees.
0644     */
0645     template<typename F>
0646     specify_except postcondition(
0647         F const&
0648         #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
0649                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0650             f
0651         #endif // Else, no name (avoid unused param warning).
0652     ) {
0653         BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_
0654     }
0655     
0656     /**
0657     Allow to specify exception guarantees.
0658 
0659     @param f    Nullary functor called by this library to check exception
0660                 guarantees @c f().
0661                 Assertions within this functor are usually programmed using
0662                 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a
0663                 call to this functor indicates a contract assertion failure (and
0664                 will result in this library calling
0665                 @RefFunc{boost::contract::except_failure}).
0666                 This functor should capture variables by (constant) references
0667                 (to access the values they will have at function exit).
0668 
0669     @return After exception guarantees have been specified, the object returned
0670             by this function does not allow to specify any additional contract.
0671     */
0672     template<typename F>
0673     specify_nothing except(
0674         F const&
0675         #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \
0676                 defined(BOOST_CONTRACT_DETAIL_DOXYGEN)
0677             f
0678         #endif // Else, no name (avoid unused param warning).
0679     ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ }
0680 
0681 /** @cond */
0682 private:
0683     BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(
0684         specify_precondition_old_postcondition_except,
0685         boost::contract::detail::cond_post<typename
0686                 boost::contract::detail::none_if_void<VirtualResult>::type>
0687     )
0688 
0689     // Friends (used to limit library's public API).
0690 
0691     friend class check;
0692     friend specify_precondition_old_postcondition_except<> function();
0693 
0694     template<class C>
0695     friend specify_precondition_old_postcondition_except<> public_function();
0696 
0697     template<class C>
0698     friend specify_precondition_old_postcondition_except<> public_function(C*);
0699     
0700     template<class C>
0701     friend specify_precondition_old_postcondition_except<> public_function(
0702             virtual_*, C*);
0703 
0704     template<typename VR, class C>
0705     friend specify_precondition_old_postcondition_except<VR> public_function(
0706             virtual_*, VR&, C*);
0707 
0708     BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
0709             O, VR, F, C, Args, v, r, f, obj, args)
0710 /** @endcond */
0711 };
0712 
0713 } } // namespace
0714 
0715 #endif // #include guard
0716