specify.hpp 26 KB

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