1 2 #ifndef BOOST_CONTRACT_SPECIFY_HPP_ 3 #define BOOST_CONTRACT_SPECIFY_HPP_ 4 5 // Copyright (C) 2008-2018 Lorenzo Caminiti 6 // Distributed under the Boost Software License, Version 1.0 (see accompanying 7 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 8 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 9 10 /** @file 11 Specify preconditions, old values copied at body, postconditions, and exception 12 guarantees 13 14 Preconditions, old values copied at body, postconditions, and exception 15 guarantees are all optionals but, when they are specified, they need to be 16 specified in that order. 17 */ 18 19 #include <boost/contract/core/config.hpp> 20 #include <boost/contract/detail/decl.hpp> 21 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 22 defined(BOOST_CONTRACT_STATIC_LINK) 23 #include <boost/contract/detail/condition/cond_base.hpp> 24 #include <boost/contract/detail/condition/cond_post.hpp> 25 #include <boost/contract/detail/auto_ptr.hpp> 26 #include <boost/contract/detail/none.hpp> 27 #endif 28 #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ 29 !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ 30 !defined(BOOST_CONTRACT_NO_EXCEPTS) 31 #include <boost/contract/detail/debug.hpp> 32 #endif 33 #include <boost/config.hpp> 34 35 // NOTE: No inheritance for faster run-times (macros to avoid duplicated code). 36 37 /* PRIVATE */ 38 39 /* @cond */ 40 41 // NOTE: Private copy ops below will force compile-time error is `auto c = ...` 42 // is used instead of `check c = ...` but only up to C++17. C++17 strong copy 43 // elision on function return values prevents this lib from generating a 44 // compile-time error in those cases, but the lib will still generate a run-time 45 // error according with ON_MISSING_CHECK_DECL. Furthermore, on some C++98 46 // compilers, this private copy ctor gives a warning (because of lack of copy 47 // optimization on those compilers), this warning can be ignored. 48 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 49 defined(BOOST_CONTRACT_STATIC_LINK) 50 #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \ 51 private: \ 52 boost::contract::detail::auto_ptr<cond_type > cond_; \ 53 explicit class_type(cond_type* cond) : cond_(cond) {} \ 54 class_type(class_type const& other) : cond_(other.cond_) {} \ 55 class_type& operator=(class_type const& other) { \ 56 cond_ = other.cond_; \ 57 return *this; \ 58 } 59 60 #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ cond_.release() 61 #else 62 #define BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(class_type, cond_type) \ 63 private: \ 64 class_type() {} \ 65 class_type(class_type const&) {} \ 66 class_type& operator=(class_type const&) { return *this; } 67 68 #define BOOST_CONTRACT_SPECIFY_COND_RELEASE_ /* nothing */ 69 #endif 70 71 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 72 #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \ 73 BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ 74 cond_->set_pre(f); \ 75 return specify_old_postcondition_except<VirtualResult>( \ 76 BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 77 #else 78 #define BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ \ 79 return specify_old_postcondition_except<VirtualResult>( \ 80 BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 81 #endif 82 83 #ifndef BOOST_CONTRACT_NO_OLDS 84 #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \ 85 BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ 86 cond_->set_old(f); \ 87 return specify_postcondition_except<VirtualResult>( \ 88 BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 89 #else 90 #define BOOST_CONTRACT_SPECIFY_OLD_IMPL_ \ 91 return specify_postcondition_except<VirtualResult>( \ 92 BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 93 #endif 94 95 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 96 #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \ 97 BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ 98 cond_->set_post(f); \ 99 return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 100 #else 101 #define BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ \ 102 return specify_except(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 103 #endif 104 105 #ifndef BOOST_CONTRACT_NO_EXCEPTS 106 #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \ 107 BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ 108 cond_->set_except(f); \ 109 return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 110 #else 111 #define BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ \ 112 return specify_nothing(BOOST_CONTRACT_SPECIFY_COND_RELEASE_); 113 #endif 114 115 /* @endcond */ 116 117 /* CODE */ 118 119 namespace boost { 120 namespace contract { 121 class virtual_; 122 123 template<typename VR> 124 class specify_precondition_old_postcondition_except; 125 126 template<typename VR> 127 class specify_old_postcondition_except; 128 129 template<typename VR> 130 class specify_postcondition_except; 131 132 class specify_except; 133 } 134 } 135 136 namespace boost { namespace contract { 137 138 /** 139 Used to prevent setting other contract conditions after exception guarantees. 140 141 This class has no member function so it is used to prevent specifying additional 142 functors to check any other contract. 143 This object is internally constructed by the library when users specify 144 contracts calling @RefFunc{boost::contract::function} and similar functions 145 (that is why this class does not have a public constructor). 146 147 @see @RefSect{tutorial, Tutorial} 148 */ 149 class specify_nothing { // Privately copyable (as *). 150 public: 151 /** 152 Destruct this object. 153 154 @b Throws: This is declared @c noexcept(false) since C++11 to allow users 155 to program failure handlers that throw exceptions on contract 156 assertion failures (not the default, see 157 @RefSect{advanced.throw_on_failures__and__noexcept__, 158 Throw on Failure}). 159 */ BOOST_NOEXCEPT_IF(false)160 ~specify_nothing() BOOST_NOEXCEPT_IF(false) {} 161 162 // No set member function here. 163 164 /** @cond */ 165 private: 166 BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_nothing, 167 boost::contract::detail::cond_base) 168 169 // Friends (used to limit library's public API). 170 171 friend class check; 172 173 template<typename VR> 174 friend class specify_precondition_old_postcondition_except; 175 176 template<typename VR> 177 friend class specify_old_postcondition_except; 178 179 template<typename VR> 180 friend class specify_postcondition_except; 181 182 friend class specify_except; 183 /** @endcond */ 184 }; 185 186 /** 187 Allow to specify exception guarantees. 188 189 Allow to specify the functor this library will call to check exception 190 guarantees. 191 This object is internally constructed by the library when users specify 192 contracts calling @RefFunc{boost::contract::function} and similar functions 193 (that is why this class does not have a public constructor). 194 195 @see @RefSect{tutorial.exception_guarantees, Exception Guarantees} 196 */ 197 class specify_except { // Privately copyable (as *). 198 public: 199 /** 200 Destruct this object. 201 202 @b Throws: This is declared @c noexcept(false) since C++11 to allow users 203 to program failure handlers that throw exceptions on contract 204 assertion failures (not the default, see 205 @RefSect{advanced.throw_on_failures__and__noexcept__, 206 Throw on Failure}). 207 */ BOOST_NOEXCEPT_IF(false)208 ~specify_except() BOOST_NOEXCEPT_IF(false) {} 209 210 /** 211 Allow to specify exception guarantees. 212 213 @param f Nullary functor called by this library to check exception 214 guarantees @c f(). 215 Assertions within this functor are usually programmed using 216 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 217 call to this functor indicates a contract assertion failure (and 218 will result in this library calling 219 @RefFunc{boost::contract::except_failure}). 220 This functor should capture variables by (constant) references 221 (to access the values they will have at function exit). 222 223 @return After exception guarantees have been specified, the object returned 224 by this function does not allow to specify any additional contract. 225 */ 226 template<typename F> except(F const & f)227 specify_nothing except( 228 F const& 229 #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ 230 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 231 f 232 #endif // Else, no name (avoid unused param warning). 233 ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } 234 235 /** @cond */ 236 private: 237 BOOST_CONTRACT_SPECIFY_CLASS_IMPL_(specify_except, 238 boost::contract::detail::cond_base) 239 240 // Friends (used to limit library's public API). 241 242 friend class check; 243 244 template<typename VR> 245 friend class specify_precondition_old_postcondition_except; 246 247 template<typename VR> 248 friend class specify_old_postcondition_except; 249 250 template<typename VR> 251 friend class specify_postcondition_except; 252 /** @endcond */ 253 }; 254 255 /** 256 Allow to specify postconditions or exception guarantees. 257 258 Allow to specify functors this library will call to check postconditions or 259 exception guarantees. 260 This object is internally constructed by the library when users specify 261 contracts calling @RefFunc{boost::contract::function} and similar functions 262 (that is why this class does not have a public constructor). 263 264 @see @RefSect{tutorial.postconditions, Postconditions}, 265 @RefSect{tutorial.exception_guarantees, Exception Guarantees} 266 267 @tparam VirtualResult Return type of the enclosing function declaring the 268 contract if that is either a virtual or an 269 overriding public function, otherwise this is always 270 @c void. 271 (Usually this template parameter is automatically 272 deduced by C++ and it does not need to be explicitly 273 specified by programmers.) 274 */ 275 template<typename VirtualResult = void> 276 class specify_postcondition_except { // Privately copyable (as *). 277 public: 278 /** 279 Destruct this object. 280 281 @b Throws: This is declared @c noexcept(false) since C++11 to allow users 282 to program failure handlers that throw exceptions on contract 283 assertion failures (not the default, see 284 @RefSect{advanced.throw_on_failures__and__noexcept__, 285 Throw on Failure}). 286 */ BOOST_NOEXCEPT_IF(false)287 ~specify_postcondition_except() BOOST_NOEXCEPT_IF(false) {} 288 289 /** 290 Allow to specify postconditions. 291 292 @param f Functor called by this library to check postconditions 293 @c f() or @c f(result). 294 Assertions within this functor are usually programmed using 295 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 296 call to this functor indicates a contract assertion failure (and 297 will result in this library calling 298 @RefFunc{boost::contract::postcondition_failure}). 299 This functor should capture variables by (constant) references 300 (to access the values they will have at function exit). 301 This functor must be a nullary functor @c f() if 302 @c VirtualResult is @c void, otherwise it must be a unary 303 functor @c f(result) accepting the return value @c result as a 304 parameter of type <c>VirtualResult const&</c> (to avoid extra 305 copies of the return value, or of type @c VirtualResult or 306 <c>VirtualResult const</c> if extra copies of the return value 307 are irrelevant). 308 309 @return After postconditions have been specified, the object returned by 310 this function allows to optionally specify exception guarantees. 311 */ 312 template<typename F> postcondition(F const & f)313 specify_except postcondition( 314 F const& 315 #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ 316 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 317 f 318 #endif // Else, no name (avoid unused param warning). 319 ) { 320 BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ 321 } 322 323 /** 324 Allow to specify exception guarantees. 325 326 @param f Nullary functor called by this library to check exception 327 guarantees @c f(). 328 Assertions within this functor are usually programmed using 329 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 330 call to this functor indicates a contract assertion failure (and 331 will result in this library calling 332 @RefFunc{boost::contract::except_failure}). 333 This functor should capture variables by (constant) references 334 (to access the values they will have at function exit). 335 336 @return After exception guarantees have been specified, the object returned 337 by this function does not allow to specify any additional contract. 338 */ 339 template<typename F> except(F const & f)340 specify_nothing except( 341 F const& 342 #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ 343 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 344 f 345 #endif // Else, no name (avoid unused param warning). 346 ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } 347 348 /** @cond */ 349 private: 350 BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( 351 specify_postcondition_except, 352 boost::contract::detail::cond_post<typename 353 boost::contract::detail::none_if_void<VirtualResult>::type> 354 ) 355 356 // Friends (used to limit library's public API). 357 358 friend class check; 359 friend class specify_precondition_old_postcondition_except<VirtualResult>; 360 friend class specify_old_postcondition_except<VirtualResult>; 361 /** @endcond */ 362 }; 363 364 /** 365 Allow to specify old values copied at body, postconditions, and exception 366 guarantees. 367 368 Allow to specify functors this library will call to copy old values at body, 369 check postconditions, and check exception guarantees. 370 This object is internally constructed by the library when users specify 371 contracts calling @RefFunc{boost::contract::function} and similar functions 372 (that is why this class does not have a public constructor). 373 374 @see @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, 375 @RefSect{tutorial.postconditions, Postconditions}, 376 @RefSect{tutorial.exception_guarantees, Exception Guarantees} 377 378 @tparam VirtualResult Return type of the enclosing function declaring the 379 contract if that is either a virtual or an 380 overriding public function, otherwise this is always 381 @c void. 382 (Usually this template parameter is automatically 383 deduced by C++ and it does not need to be explicitly 384 specified by programmers.) 385 */ 386 template<typename VirtualResult = void> 387 class specify_old_postcondition_except { // Privately copyable (as *). 388 public: 389 /** 390 Destruct this object. 391 392 @b Throws: This is declared @c noexcept(false) since C++11 to allow users 393 to program failure handlers that throw exceptions on contract 394 assertion failures (not the default, see 395 @RefSect{advanced.throw_on_failures__and__noexcept__, 396 Throw on Failure}). 397 */ BOOST_NOEXCEPT_IF(false)398 ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} 399 400 /** 401 Allow to specify old values copied at body. 402 403 It should often be sufficient to initialize old value pointers as soon as 404 they are declared, without using this function (see 405 @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). 406 407 @param f Nullary functor called by this library @c f() to assign old 408 value copies just before the body is executed but after entry 409 invariants (when they apply) and preconditions are checked. 410 Old value pointers within this functor call are usually assigned 411 using @RefMacro{BOOST_CONTRACT_OLDOF}. 412 Any exception thrown by a call to this functor will result in 413 this library calling @RefFunc{boost::contract::old_failure} 414 (because old values could not be copied to check postconditions 415 and exception guarantees). 416 This functor should capture old value pointers by references so 417 they can be assigned (all other variables needed to evaluate old 418 value expressions can be captured by (constant) value, or better 419 by (constant) reference to avoid extra copies). 420 421 @return After old values copied at body have been specified, the object 422 returned by this function allows to optionally specify 423 postconditions and exception guarantees. 424 */ 425 template<typename F> old(F const & f)426 specify_postcondition_except<VirtualResult> old( 427 F const& 428 #if !defined(BOOST_CONTRACT_NO_OLDS) || \ 429 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 430 f 431 #endif // Else, no name (avoid unused param warning). 432 ) { 433 BOOST_CONTRACT_SPECIFY_OLD_IMPL_ 434 } 435 436 /** 437 Allow to specify postconditions. 438 439 @param f Functor called by this library to check postconditions 440 @c f() or @c f(result). 441 Assertions within this functor are usually programmed using 442 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 443 call to this functor indicates a contract assertion failure (and 444 will result in this library calling 445 @RefFunc{boost::contract::postcondition_failure}). 446 This functor should capture variables by (constant) references 447 (to access the values they will have at function exit). 448 This functor must be a nullary functor @c f() if 449 @c VirtualResult is @c void, otherwise it must be a unary 450 functor @c f(result) accepting the return value @c result as a 451 parameter of type <c>VirtualResult const&</c> (to avoid extra 452 copies of the return value, or of type @c VirtualResult or 453 <c>VirtualResult const</c> if extra copies of the return value 454 are irrelevant). 455 456 @return After postconditions have been specified, the object returned by 457 this function allows to optionally specify exception guarantees. 458 */ 459 template<typename F> postcondition(F const & f)460 specify_except postcondition( 461 F const& 462 #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ 463 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 464 f 465 #endif // Else, no name (avoid unused param warning). 466 ) { 467 BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ 468 } 469 470 /** 471 Allow to specify exception guarantees. 472 473 @param f Nullary functor called by this library to check exception 474 guarantees @c f(). 475 Assertions within this functor are usually programmed using 476 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 477 call to this functor indicates a contract assertion failure (and 478 will result in this library calling 479 @RefFunc{boost::contract::except_failure}). 480 This functor should capture variables by (constant) references 481 (to access the values they will have at function exit). 482 483 @return After exception guarantees have been specified, the object returned 484 by this function does not allow to specify any additional contract. 485 */ 486 template<typename F> except(F const & f)487 specify_nothing except( 488 F const& 489 #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ 490 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 491 f 492 #endif // Else, no name (avoid unused param warning). 493 ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } 494 495 /** @cond */ 496 private: 497 BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( 498 specify_old_postcondition_except, 499 boost::contract::detail::cond_post<typename 500 boost::contract::detail::none_if_void<VirtualResult>::type> 501 ) 502 503 // Friends (used to limit library's public API). 504 505 friend class check; 506 friend class specify_precondition_old_postcondition_except<VirtualResult>; 507 508 template<class C> 509 friend specify_old_postcondition_except<> constructor(C*); 510 511 template<class C> 512 friend specify_old_postcondition_except<> destructor(C*); 513 /** @endcond */ 514 }; 515 516 /** 517 Allow to specify preconditions, old values copied at body, postconditions, and 518 exception guarantees. 519 520 Allow to specify functors this library will call to check preconditions, copy 521 old values at body, check postconditions, and check exception guarantees. 522 This object is internally constructed by the library when users specify 523 contracts calling @RefFunc{boost::contract::function} and similar functions 524 (that is why this class does not have a public constructor). 525 526 @see @RefSect{tutorial.preconditions, Preconditions}, 527 @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, 528 @RefSect{tutorial.postconditions, Postconditions}, 529 @RefSect{tutorial.exception_guarantees, Exception Guarantees} 530 531 @tparam VirtualResult Return type of the enclosing function declaring the 532 contract if that is either a virtual or an 533 overriding public function, otherwise this is always 534 @c void. 535 (Usually this template parameter is automatically 536 deduced by C++ and it does not need to be explicitly 537 specified by programmers.) 538 */ 539 template< 540 typename VirtualResult /* = void (already in fwd decl from decl.hpp) */ 541 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 542 = void 543 #endif 544 > 545 class specify_precondition_old_postcondition_except { // Priv. copyable (as *). 546 public: 547 /** 548 Destruct this object. 549 550 @b Throws: This is declared @c noexcept(false) since C++11 to allow users 551 to program failure handlers that throw exceptions on contract 552 assertion failures (not the default, see 553 @RefSect{advanced.throw_on_failures__and__noexcept__, 554 Throw on Failure}). 555 */ BOOST_NOEXCEPT_IF(false)556 ~specify_precondition_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} 557 558 /** 559 Allow to specify preconditions. 560 561 @param f Nullary functor called by this library to check preconditions 562 @c f(). 563 Assertions within this functor are usually programmed using 564 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 565 call to this functor indicates a contract assertion failure (and 566 will result in this library calling 567 @RefFunc{boost::contract::precondition_failure}). 568 This functor should capture variables by (constant) value, or 569 better by (constant) reference (to avoid extra copies). 570 571 @return After preconditions have been specified, the object returned by this 572 function allows to optionally specify old values copied at body, 573 postconditions, and exception guarantees. 574 */ 575 template<typename F> precondition(F const & f)576 specify_old_postcondition_except<VirtualResult> precondition( 577 F const& 578 #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ 579 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 580 f 581 #endif // Else, no name (avoid unused param warning). 582 ) { 583 BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ 584 } 585 586 /** 587 Allow to specify old values copied at body. 588 589 It should often be sufficient to initialize old value pointers as soon as 590 they are declared, without using this function (see 591 @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). 592 593 @param f Nullary functor called by this library @c f() to assign old 594 value copies just before the body is executed but after entry 595 invariants (when they apply) and preconditions are checked. 596 Old value pointers within this functor call are usually assigned 597 using @RefMacro{BOOST_CONTRACT_OLDOF}. 598 Any exception thrown by a call to this functor will result in 599 this library calling @RefFunc{boost::contract::old_failure} 600 (because old values could not be copied to check postconditions 601 and exception guarantees). 602 This functor should capture old value pointers by references so 603 they can be assigned (all other variables needed to evaluate old 604 value expressions can be captured by (constant) value, or better 605 by (constant) reference to avoid extra copies). 606 607 @return After old values copied at body have been specified, the object 608 returned by this functions allows to optionally specify 609 postconditions and exception guarantees. 610 */ 611 template<typename F> old(F const & f)612 specify_postcondition_except<VirtualResult> old( 613 F const& 614 #if !defined(BOOST_CONTRACT_NO_OLDS) || \ 615 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 616 f 617 #endif // Else, no name (avoid unused param warning). 618 ) { 619 BOOST_CONTRACT_SPECIFY_OLD_IMPL_ 620 } 621 622 /** 623 Allow to specify postconditions. 624 625 @param f Functor called by this library to check postconditions 626 @c f() or @c f(result). 627 Assertions within this functor are usually programmed using 628 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 629 call to this functor indicates a contract assertion failure (and 630 will result in this library calling 631 @RefFunc{boost::contract::postcondition_failure}). 632 This functor should capture variables by (constant) references 633 (to access the values they will have at function exit). 634 This functor must be a nullary functor @c f() if 635 @c VirtualResult is @c void, otherwise it must be a unary 636 functor @c f(result) accepting the return value @c result as a 637 parameter of type <c>VirtualResult const&</c> (to avoid extra 638 copies of the return value, or of type @c VirtualResult or 639 <c>VirtualResult const</c> if extra copies of the return value 640 are irrelevant). 641 642 @return After postconditions have been specified, the object returned by 643 this function allows to optionally specify exception guarantees. 644 */ 645 template<typename F> postcondition(F const & f)646 specify_except postcondition( 647 F const& 648 #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ 649 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 650 f 651 #endif // Else, no name (avoid unused param warning). 652 ) { 653 BOOST_CONTRACT_SPECIFY_POSTCONDITION_IMPL_ 654 } 655 656 /** 657 Allow to specify exception guarantees. 658 659 @param f Nullary functor called by this library to check exception 660 guarantees @c f(). 661 Assertions within this functor are usually programmed using 662 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a 663 call to this functor indicates a contract assertion failure (and 664 will result in this library calling 665 @RefFunc{boost::contract::except_failure}). 666 This functor should capture variables by (constant) references 667 (to access the values they will have at function exit). 668 669 @return After exception guarantees have been specified, the object returned 670 by this function does not allow to specify any additional contract. 671 */ 672 template<typename F> except(F const & f)673 specify_nothing except( 674 F const& 675 #if !defined(BOOST_CONTRACT_NO_EXCEPTS) || \ 676 defined(BOOST_CONTRACT_DETAIL_DOXYGEN) 677 f 678 #endif // Else, no name (avoid unused param warning). 679 ) { BOOST_CONTRACT_SPECIFY_EXCEPT_IMPL_ } 680 681 /** @cond */ 682 private: 683 BOOST_CONTRACT_SPECIFY_CLASS_IMPL_( 684 specify_precondition_old_postcondition_except, 685 boost::contract::detail::cond_post<typename 686 boost::contract::detail::none_if_void<VirtualResult>::type> 687 ) 688 689 // Friends (used to limit library's public API). 690 691 friend class check; 692 friend specify_precondition_old_postcondition_except<> function(); 693 694 template<class C> 695 friend specify_precondition_old_postcondition_except<> public_function(); 696 697 template<class C> 698 friend specify_precondition_old_postcondition_except<> public_function(C*); 699 700 template<class C> 701 friend specify_precondition_old_postcondition_except<> public_function( 702 virtual_*, C*); 703 704 template<typename VR, class C> 705 friend specify_precondition_old_postcondition_except<VR> public_function( 706 virtual_*, VR&, C*); 707 708 BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1, 709 O, VR, F, C, Args, v, r, f, obj, args) 710 /** @endcond */ 711 }; 712 713 } } // namespace 714 715 #endif // #include guard 716 717