contract_macro.hpp 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409
  1. #ifndef BOOST_CONTRACT_MACRO_HPP_
  2. #define BOOST_CONTRACT_MACRO_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. Allow to disable contracts to completely remove their compile-time and run-time
  9. overhead.
  10. This header automatically includes all header files <c>boost/contract/\*.hpp</c>
  11. necessary to use its macros.
  12. Almost all the macros defined in this header file are variadic macros. On
  13. compilers that do not support variadic macros, programmers can manually code
  14. <c>\#ifndef BOOST_CONTRACT_NO_...</c> statements instead (see
  15. @RefSect{extras.disable_contract_compilation__macro_interface_,
  16. Disable Contract Compilation}).
  17. */
  18. // IMPORTANT: Following headers can always be #included (without any #if-guard)
  19. // because they expand to trivial code that does not affect compile-time. These
  20. // headers must always be #included here (without any #if-guard) because they
  21. // define types and macros that are typically left in user code even when
  22. // contracts are disables (these types and macros never affect run-time and
  23. // their definitions are trivial when contracts are disabled so their impact on
  24. // compile-time is negligible).
  25. #include <boost/contract/override.hpp>
  26. #include <boost/contract/base_types.hpp>
  27. #include <boost/contract/core/constructor_precondition.hpp>
  28. #include <boost/contract/core/check_macro.hpp>
  29. #include <boost/contract/core/access.hpp>
  30. #include <boost/contract/core/virtual.hpp>
  31. #include <boost/contract/core/exception.hpp>
  32. #include <boost/contract/core/config.hpp>
  33. #ifndef BOOST_CONTRACT_NO_CONDITIONS
  34. #include <boost/contract/assert.hpp>
  35. #endif
  36. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  37. /**
  38. Program preconditions that can be completely disabled at compile-time.
  39. @c BOOST_CONTRACT_PRECONDITION(f) expands to code equivalent to the
  40. following (note that no code is generated when
  41. @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined):
  42. @code
  43. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  44. .precondition(f)
  45. #endif
  46. @endcode
  47. Where:
  48. @arg <c><b>f</b></c> is the nullay functor called by this library to
  49. check preconditions @c f().
  50. Assertions within this functor are usually programmed using
  51. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  52. to this functor indicates a contract assertion failure (and will
  53. result in this library calling
  54. @RefFunc{boost::contract::precondition_failure}).
  55. This functor should capture variables by (constant) value, or better
  56. by (constant) reference (to avoid extra copies).
  57. (This is a variadic macro parameter so it can contain commas not
  58. protected by round parenthesis.)
  59. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  60. Disable Contract Compilation},
  61. @RefSect{tutorial.preconditions, Preconditions}
  62. */
  63. #define BOOST_CONTRACT_PRECONDITION(...)
  64. #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS)
  65. #define BOOST_CONTRACT_PRECONDITION(...) .precondition(__VA_ARGS__)
  66. #else
  67. #define BOOST_CONTRACT_PRECONDITION(...) /* nothing */
  68. #endif
  69. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  70. /**
  71. Program postconditions that can be completely disabled at compile-time.
  72. @c BOOST_CONTRACT_POSTCONDITION(f) expands to code equivalent to the
  73. following (note that no code is generated when
  74. @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} is defined):
  75. @code
  76. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  77. .postcondition(f)
  78. #endif
  79. @endcode
  80. Where:
  81. @arg <c><b>f</b></c> is the functor called by this library to check
  82. postconditions @c f() or @c f(result).
  83. Assertions within this functor are usually programmed using
  84. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  85. to this functor indicates a contract assertion failure (and will
  86. result in this library calling
  87. @RefFunc{boost::contract::postcondition_failure}).
  88. This functor should capture variables by (constant) references (to
  89. access the values they will have at function exit).
  90. This functor takes the return value (preferably by <c>const&</c>)
  91. @c result as its one single parameter @c f(result) but only for
  92. virtual public functions and public functions overrides, otherwise
  93. it takes no parameter @c f().
  94. (This is a variadic macro parameter so it can contain commas not
  95. protected by round parenthesis.)
  96. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  97. Disable Contract Compilation},
  98. @RefSect{tutorial.postconditions, Postconditions}
  99. */
  100. #define BOOST_CONTRACT_POSTCONDITION(...)
  101. #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS)
  102. #define BOOST_CONTRACT_POSTCONDITION(...) .postcondition(__VA_ARGS__)
  103. #else
  104. #define BOOST_CONTRACT_POSTCONDITION(...) /* nothing */
  105. #endif
  106. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  107. /**
  108. Program exception guarantees that can be completely disabled at
  109. compile-time.
  110. @c BOOST_CONTRACT_EXCEPT(f) expands to code equivalent to the following
  111. (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}
  112. is defined):
  113. @code
  114. #ifndef BOOST_CONTRACT_NO_EXCEPTS
  115. .except(f)
  116. #endif
  117. @endcode
  118. Where:
  119. @arg <c><b>f</b></c> is the nullary functor called by this library to
  120. check exception guarantees @c f().
  121. Assertions within this functor are usually programmed using
  122. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  123. to this functor indicates a contract assertion failure (and will
  124. result in this library calling
  125. @RefFunc{boost::contract::except_failure}).
  126. This functor should capture variables by (constant) references (to
  127. access the values they will have at function exit).
  128. (This is a variadic macro parameter so it can contain commas not
  129. protected by round parenthesis.)
  130. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  131. Disable Contract Compilation},
  132. @RefSect{tutorial.exception_guarantees, Exception Guarantees}
  133. */
  134. #define BOOST_CONTRACT_EXCEPT(...)
  135. #elif !defined(BOOST_CONTRACT_NO_EXCEPTS)
  136. #define BOOST_CONTRACT_EXCEPT(...) .except(__VA_ARGS__)
  137. #else
  138. #define BOOST_CONTRACT_EXCEPT(...) /* nothing */
  139. #endif
  140. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  141. /**
  142. Program old value copies at body that can be completely disabled at
  143. compile-time.
  144. @c BOOST_CONTRACT_OLD(f) expands to code equivalent to the following (note
  145. that no code is generated when @RefMacro{BOOST_CONTRACT_NO_OLDS} is
  146. defined):
  147. @code
  148. #ifndef BOOST_CONTRACT_NO_OLDS
  149. .old(f)
  150. #endif
  151. @endcode
  152. Where:
  153. @arg <c><b>f</b></c> is the nullary functor called by this library
  154. @c f() to assign old value copies just before the body is execute
  155. but after entry invariants (when they apply) and preconditions are
  156. checked.
  157. Old value pointers within this functor call are usually assigned
  158. using @RefMacro{BOOST_CONTRACT_OLDOF}.
  159. Any exception thrown by a call to this functor will result in
  160. this library calling @RefFunc{boost::contract::old_failure} (because
  161. old values could not be copied to check postconditions and exception
  162. guarantees).
  163. This functor should capture old value pointers by references so they
  164. can be assigned (all other variables needed to evaluate old value
  165. expressions can be captured by (constant) value, or better by
  166. (constant) reference to avoid extra copies).
  167. (This is a variadic macro parameter so it can contain commas not
  168. protected by round parenthesis.)
  169. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  170. Disable Contract Compilation},
  171. @RefSect{advanced.old_values_copied_at_body,
  172. Old Values Copied at Body}
  173. */
  174. #define BOOST_CONTRACT_OLD(...)
  175. /**
  176. Program old values that can be completely disabled at compile-time for old
  177. value types that are required to be copyable.
  178. This is used to program old value copies for copyable types:
  179. @code
  180. class u {
  181. public:
  182. void f(...) {
  183. BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // Null...
  184. BOOST_CONTRACT_OLD_PTR(old_type_b)(old_var_b, old_expr_b); // Set.
  185. BOOST_CONTRACT_PUBLIC_FUNCTION(this)
  186. ...
  187. BOOST_CONTRACT_OLD([&] {
  188. old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); // ...set.
  189. ...
  190. })
  191. ...
  192. ;
  193. ... // Function body.
  194. }
  195. virtual void g(..., boost::contract::virtual_* v = 0) {
  196. BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // No `v`
  197. BOOST_CONTRACT_OLD_PTR(old_type_b)(v, old_var_b, old_expr_b); // `v`
  198. BOOST_CONTRACT_PUBLIC_FUNCTION(v, this)
  199. ...
  200. BOOST_CONTRACT_OLD([&] {
  201. old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); // `v`
  202. ...
  203. })
  204. ...
  205. ;
  206. ... // Function body.
  207. }
  208. ...
  209. };
  210. @endcode
  211. This is an overloaded variadic macro and it can be used in the following
  212. different ways (note that no code is generated when
  213. @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined).
  214. 1\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var)</c> expands to code
  215. equivalent to the following (this leaves the old value pointer null):
  216. @code
  217. #ifndef BOOST_CONTRACT_NO_OLDS
  218. // This declaration does not need to use `v`.
  219. boost::contract::old_ptr<old_type> old_var
  220. #endif
  221. @endcode
  222. 2\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var, old_expr)</c> expands to
  223. code equivalent to the following (this initializes the pointer to the
  224. old value copy, but not to be used for virtual public functions and
  225. public function overrides):
  226. @code
  227. #ifndef BOOST_CONTRACT_NO_OLDS
  228. boost::contract::old_ptr<old_type> old_var =
  229. BOOST_CONTRACT_OLDOF(old_expr)
  230. #endif
  231. @endcode
  232. 3\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, old_expr)</c> expands to
  233. code equivalent to the following (this initializes the pointer to the
  234. old value copy for virtual public functions and public function
  235. overrides):
  236. @code
  237. #ifndef BOOST_CONTRACT_NO_OLDS
  238. boost::contract::old_ptr<old_type> old_var =
  239. BOOST_CONTRACT_OLDOF(v, old_expr)
  240. #endif
  241. @endcode
  242. Where:
  243. @arg <c><b>old_type</b></c> is the type of the pointed old value.
  244. This type must be copyable (i.e.,
  245. <c>boost::contract::is_old_value_copyable<old_type>::value</c> is
  246. @c true), otherwise this pointer will always be null and this
  247. library will generate a compile-time error when the pointer is
  248. dereferenced (see @RefMacro{BOOST_CONTRACT_OLD_PTR_IF_COPYABLE}).
  249. (This is a variadic macro parameter so it can contain commas not
  250. protected by round parenthesis.)
  251. (Rationale: Template parameters like this one are specified to
  252. this library macro interface using their own set of parenthesis
  253. <c>SOME_MACRO(template_params)(other_params)</c>.)
  254. @arg <c><b>v</b></c> is the extra training parameter of type
  255. @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
  256. from the enclosing virtual public function or public function
  257. override declaring the contract.
  258. (This is not a variadic macro parameter but it should never contain
  259. commas because it is an identifier.)
  260. @arg <c><b>old_var</b></c> is the name of the old value pointer variable.
  261. (This is not a variadic macro parameter but it should never contain
  262. commas because it is an identifier.)
  263. @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied
  264. in the old value pointer.
  265. (This is not a variadic macro parameter so any comma it might
  266. contain must be protected by round parenthesis and
  267. <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, (old_expr))</c>
  268. will always work.)
  269. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  270. Disable Contract Compilation},
  271. @RefSect{tutorial.old_values, Old Values}
  272. */
  273. #define BOOST_CONTRACT_OLD_PTR(...)
  274. /**
  275. Program old values that can be completely disabled at compile-time for old
  276. value types that are not required to be copyable.
  277. This is used to program old value copies for types that might or might not
  278. be copyable:
  279. @code
  280. template<typename T> // Type `T` might or not be copyable.
  281. class u {
  282. public:
  283. void f(...) {
  284. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a);
  285. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(old_var_b,
  286. old_expr_b);
  287. BOOST_CONTRACT_PUBLIC_FUNCTION(this)
  288. ...
  289. BOOST_CONTRACT_OLD([&] {
  290. old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a);
  291. ...
  292. })
  293. ... // In postconditions or exception guarantees:
  294. if(old_var_a) ... // Always null for non-copyable types.
  295. if(old_var_b) ... // Always null for non-copyable types.
  296. ...
  297. ;
  298. ... // Function body.
  299. }
  300. virtual void g(..., boost::contract::virtual_* v = 0) {
  301. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a);
  302. BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(v, old_var_b,
  303. old_expr_b);
  304. BOOST_CONTRACT_PUBLIC_FUNCTION(v, this)
  305. ...
  306. BOOST_CONTRACT_OLD([&] {
  307. old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a);
  308. ...
  309. })
  310. ... // In postconditions or exception guarantees:
  311. if(old_var_a) ... // Always null for non-copyable types.
  312. if(old_var_b) ... // Always null for non-copyable types.
  313. ...
  314. ;
  315. ... // Function body.
  316. }
  317. ...
  318. };
  319. @endcode
  320. This is an overloaded variadic macro and it can be used in the following
  321. different ways (note that no code is generated when
  322. @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined).
  323. 1\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var)</c> expands to
  324. code equivalent to the following (this leaves the old value pointer
  325. null):
  326. @code
  327. #ifndef BOOST_CONTRACT_NO_OLDS
  328. // This declaration does not need to use `v`.
  329. boost::contract::old_ptr_if_copyable<old_type> old_var
  330. #endif
  331. @endcode
  332. 2\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var, old_expr)</c>
  333. expands to code equivalent to the following (this initializes the
  334. pointer to the old value copy, but not to be used for virtual public
  335. functions and public function overrides):
  336. @code
  337. #ifndef BOOST_CONTRACT_NO_OLDS
  338. boost::contract::old_ptr_if_copyable<old_type> old_var =
  339. BOOST_CONTRACT_OLDOF(old_expr)
  340. #endif
  341. @endcode
  342. 3\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var,
  343. old_expr)</c> expands to code equivalent to the following (this
  344. initializes the pointer to the old value copy for virtual public
  345. functions and public function overrides):
  346. @code
  347. #ifndef BOOST_CONTRACT_NO_OLDS
  348. boost::contract::old_ptr_if_copyable<old_type> old_var =
  349. BOOST_CONTRACT_OLDOF(v, old_expr)
  350. #endif
  351. @endcode
  352. Where:
  353. @arg <c><b>old_type</b></c> is the type of the pointed old value.
  354. If this type is not copyable (i.e.,
  355. <c>boost::contract::is_old_value_copyable<old_type>::value</c> is
  356. @c false), this pointer will always be null, but this library will
  357. not generate a compile-time error when this pointer is dereferenced
  358. (see @RefMacro{BOOST_CONTRACT_OLD_PTR}).
  359. (This is a variadic macro parameter so it can contain commas not
  360. protected by round parenthesis.)
  361. @arg <c><b>v</b></c> is the extra trailing parameter of type
  362. @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
  363. from the enclosing virtual public function or public function
  364. override declaring the contract.
  365. (This is not a variadic macro parameter but it should never contain
  366. commas because it is an identifier.)
  367. @arg <c><b>old_var</b></c> is the name of the old value pointer variable.
  368. (This is not a variadic macro parameter but it should never contain
  369. commas because it is an identifier.)
  370. @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied
  371. in the old value pointer.
  372. (This is not a variadic macro parameter so any comma it might
  373. contain must be protected by round parenthesis and
  374. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var,
  375. (old_expr))</c> will always work.)
  376. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  377. Disable Contract Compilation},
  378. @RefSect{extras.old_value_requirements__templates_,
  379. Old Value Requirements}
  380. */
  381. #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...)
  382. #elif !defined(BOOST_CONTRACT_NO_OLDS)
  383. #include <boost/contract/old.hpp>
  384. #include <boost/preprocessor/facilities/overload.hpp>
  385. #include <boost/preprocessor/facilities/empty.hpp>
  386. #include <boost/preprocessor/cat.hpp>
  387. /* PRIVATE */
  388. #define BOOST_CONTRACT_OLD_VAR_1(ptr) \
  389. ptr
  390. #define BOOST_CONTRACT_OLD_VAR_2(ptr, expr) \
  391. ptr = BOOST_CONTRACT_OLDOF(expr)
  392. #define BOOST_CONTRACT_OLD_VAR_3(v, ptr, expr) \
  393. ptr = BOOST_CONTRACT_OLDOF(v, expr)
  394. #define BOOST_CONTRACT_OLD_VAR_(...) \
  395. BOOST_PP_CAT(BOOST_PP_OVERLOAD(BOOST_CONTRACT_OLD_VAR_, __VA_ARGS__) \
  396. (__VA_ARGS__), BOOST_PP_EMPTY())
  397. /* PUBLIC */
  398. #define BOOST_CONTRACT_OLD(...) .old(__VA_ARGS__)
  399. #define BOOST_CONTRACT_OLD_PTR(...) \
  400. boost::contract::old_ptr< __VA_ARGS__ > \
  401. BOOST_CONTRACT_OLD_VAR_
  402. #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) \
  403. boost::contract::old_ptr_if_copyable< __VA_ARGS__ > \
  404. BOOST_CONTRACT_OLD_VAR_
  405. #else
  406. #include <boost/preprocessor/tuple/eat.hpp>
  407. #define BOOST_CONTRACT_OLD(...) /* nothing */
  408. #define BOOST_CONTRACT_OLD_PTR(...) BOOST_PP_TUPLE_EAT(0)
  409. #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) BOOST_PP_TUPLE_EAT(0)
  410. #endif
  411. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  412. /**
  413. Program (constant) class invariants that can be completely disabled at
  414. compile-time.
  415. @c BOOST_CONTRACT_INVARIANT({ ... }) expands to code equivalent to the
  416. following (note that no code is generated when
  417. @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined):
  418. @code
  419. #ifndef BOOST_CONTRACT_NO_INVARIANTS
  420. void BOOST_CONTRACT_INVARIANT_FUNC() const {
  421. ...
  422. }
  423. #endif
  424. @endcode
  425. Where:
  426. @arg <b>{ ... }</b> is the definition of the function that checks class
  427. invariants for public functions that are not static and not volatile
  428. (see @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT} and
  429. @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}).
  430. The curly parenthesis are mandatory (rationale: this is so the
  431. syntax of this macro resembles mote the syntax of the lambda
  432. functions usually used to specify preconditions, etc.).
  433. Assertions within this function are usually programmed using
  434. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  435. to this function indicates a contract assertion failure (and will
  436. result in this library calling either
  437. @RefFunc{boost::contract::entry_invariant_failure} or
  438. @RefFunc{boost::contract::exit_invariant_failure}).
  439. (This is a variadic macro parameter so it can contain commas not
  440. protected by round parenthesis.)
  441. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  442. Disable Contract Compilation},
  443. @RefSect{tutorial.class_invariants, Class Invariants}
  444. */
  445. #define BOOST_CONTRACT_INVARIANT(...)
  446. /**
  447. Program volatile class invariants that can be completely disabled at
  448. compile-time.
  449. @c BOOST_CONTRACT_INVARIANT_VOLATILE({ ... }) expands to code equivalent to
  450. the following (note that no code is generated when
  451. @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined):
  452. @code
  453. #ifndef BOOST_CONTRACT_NO_INVARIANTS
  454. void BOOST_CONTRACT_INVARIANT_FUNC() const volatile {
  455. ...
  456. }
  457. #endif
  458. @endcode
  459. Where:
  460. @arg <b>{ ... }</b> is the definition of the function that checks class
  461. invariants for volatile public functions
  462. (see @RefMacro{BOOST_CONTRACT_INVARIANT} and
  463. @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}).
  464. The curly parenthesis are mandatory.
  465. Assertions within this function are usually programmed using
  466. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  467. to this function indicates a contract assertion failure (and will
  468. result in this library calling either
  469. @RefFunc{boost::contract::entry_invariant_failure} or
  470. @RefFunc{boost::contract::exit_invariant_failure}).
  471. (This is a variadic macro parameter so it can contain commas not
  472. protected by round parenthesis.)
  473. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  474. Disable Contract Compilation},
  475. @RefSect{extras.volatile_public_functions,
  476. Volatile Public Functions}
  477. */
  478. #define BOOST_CONTRACT_INVARIANT_VOLATILE(...)
  479. /**
  480. Program static class invariants that can be completely disabled at
  481. compile-time.
  482. @c BOOST_CONTRACT_STATIC_INVARIANT({ ... }) expands to code equivalent to
  483. the following (note that no code is generated when
  484. @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined):
  485. @code
  486. #ifndef BOOST_CONTRACT_NO_INVARIANTS
  487. static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() {
  488. ...
  489. }
  490. #endif
  491. @endcode
  492. Where:
  493. @arg <b>{ ... }</b> is the definition of the function that checks class
  494. invariants for static public functions
  495. (see @RefMacro{BOOST_CONTRACT_INVARIANT} and
  496. @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}).
  497. The curly parenthesis are mandatory.
  498. Assertions within this function are usually programmed using
  499. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  500. to this function indicates a contract assertion failure (and will
  501. result in this library calling either
  502. @RefFunc{boost::contract::entry_invariant_failure} or
  503. @RefFunc{boost::contract::exit_invariant_failure}).
  504. (This is a variadic macro parameter so it can contain commas not
  505. protected by round parenthesis.)
  506. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  507. Disable Contract Compilation},
  508. @RefSect{tutorial.class_invariants, Class Invariants}
  509. */
  510. #define BOOST_CONTRACT_STATIC_INVARIANT(...)
  511. #elif !defined(BOOST_CONTRACT_NO_INVARIANTS)
  512. #include <boost/contract/core/config.hpp>
  513. #define BOOST_CONTRACT_INVARIANT(...) \
  514. void BOOST_CONTRACT_INVARIANT_FUNC() const __VA_ARGS__
  515. #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) \
  516. void BOOST_CONTRACT_INVARIANT_FUNC() const volatile __VA_ARGS__
  517. #define BOOST_CONTRACT_STATIC_INVARIANT(...) \
  518. static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() __VA_ARGS__
  519. #else
  520. #define BOOST_CONTRACT_INVARIANT(...) /* nothing */
  521. #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) /* nothing */
  522. #define BOOST_CONTRACT_STATIC_INVARIANT(...) /* nothing */
  523. #endif
  524. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  525. /**
  526. Program contracts that can be completely disabled at compile-time for
  527. constructors.
  528. This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION},
  529. @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to
  530. specify postconditions, exception guarantees, and old value copies at body
  531. that can be completely disabled at compile-time for constructors (see
  532. @RefMacro{BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION} to specify preconditions
  533. for constructors):
  534. @code
  535. class u {
  536. friend class boost::contract::access;
  537. BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile).
  538. BOOST_CONTRACT_ASSERT(...);
  539. ...
  540. })
  541. public:
  542. u(...) {
  543. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  544. BOOST_CONTRACT_CONSTRUCTOR(this)
  545. // No `PRECONDITION` (use `CONSTRUCTOR_PRECONDITION` if needed).
  546. BOOST_CONTRACT_OLD([&] { // Optional.
  547. old_var = BOOST_CONTRACT_OLDOF(old_epxr);
  548. ...
  549. })
  550. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  551. BOOST_CONTRACT_ASSERT(...);
  552. ...
  553. })
  554. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  555. BOOST_CONTRACT_ASSERT(...);
  556. ...
  557. })
  558. ; // Trailing `;` is required.
  559. ... // Constructor body.
  560. }
  561. ...
  562. };
  563. @endcode
  564. For optimization, this can be omitted for constructors that do not have
  565. postconditions and exception guarantees, within classes that have no
  566. invariants.
  567. @c BOOST_CONTRACT_CONSTRUCTOR(obj) expands to code equivalent to the
  568. following (note that no code is generated when
  569. @RefMacro{BOOST_CONTRACT_NO_CONSTRUCTORS} is defined):
  570. @code
  571. #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS
  572. boost::contract::check internal_var =
  573. boost::contract::constructor(obj)
  574. #endif
  575. @endcode
  576. Where:
  577. @arg <c><b>obj</b></c> is the object @c this from the scope of the
  578. enclosing constructor declaring the contract.
  579. Constructors check all class invariants, including static and
  580. volatile invariants (see @RefMacro{BOOST_CONTRACT_INVARIANT},
  581. @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}, and
  582. @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}).
  583. (This is a variadic macro parameter so it can contain commas not
  584. protected by round parenthesis.)
  585. @arg <c><b>internal_var</b></c> is a variable name internally generated
  586. by this library (this name is unique but only on different line
  587. numbers so this macro cannot be expanded multiple times on the same
  588. line).
  589. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  590. Disable Contract Compilation},
  591. @RefSect{tutorial.constructors, Constructors}
  592. */
  593. #define BOOST_CONTRACT_CONSTRUCTOR(...)
  594. #elif !defined(BOOST_CONTRACT_NO_CONSTRUCTORS)
  595. #include <boost/contract/constructor.hpp>
  596. #include <boost/contract/check.hpp>
  597. #include <boost/contract/detail/name.hpp>
  598. #define BOOST_CONTRACT_CONSTRUCTOR(...) \
  599. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  600. boost::contract::constructor(__VA_ARGS__)
  601. #else
  602. #define BOOST_CONTRACT_CONSTRUCTOR(...) /* nothing */
  603. #endif
  604. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  605. /**
  606. Program preconditions that can be disabled at compile-time for constructors.
  607. This is used together with @RefMacro{BOOST_CONTRACT_CONSTRUCTOR} to specify
  608. contracts for constructors.
  609. Constructors that do not have preconditions do not use this macro.
  610. When at least one of the class constructors uses this macro,
  611. @RefClass{boost::contract::constructor_precondition} must be the first and
  612. private base of the class declaring the constructor for which preconditions
  613. are programmed:
  614. @code
  615. class u
  616. #define BASES private boost::contract::constructor_precondition<u>, \
  617. public b
  618. : BASES
  619. {
  620. friend class boost::contract::access;
  621. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  622. #undef BASES
  623. ...
  624. public:
  625. explicit u(unsigned x) :
  626. BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(u)([&] {
  627. BOOST_CONTRACT_ASSERT(x != 0);
  628. }),
  629. b(1 / x)
  630. {
  631. ...
  632. }
  633. ...
  634. };
  635. @endcode
  636. <c>BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(class_type)(f)</c> expands
  637. to code equivalent to the following (note that when
  638. @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined, this macro trivially
  639. expands to a default constructor call that is internally implemented to do
  640. nothing so this should have minimal to no overhead):
  641. @code
  642. // Guarded only by NO_PRECONDITIONS (and not also by NO_CONSTRUCTORS)
  643. // because for constructor's preconditions (not for postconditions, etc.).
  644. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  645. boost::contract::constructor_precondition<class_type>(f)
  646. #else // No-op call (likely optimized away, minimal to no overhead).
  647. boost::contract::constructor_precondition<class_type>()
  648. #endif
  649. @endcode
  650. Where:
  651. @arg <c><b>class_type</b></c> is the type of the class containing the
  652. constructor for which preconditions are being programmed.
  653. (This is a variadic macro parameter so it can contain commas not
  654. protected by round parenthesis.)
  655. @arg <c><b>f</b></c> is the nullary functor called by this library to
  656. check constructor preconditions @c f().
  657. Assertions within this functor call are usually programmed using
  658. @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call
  659. to this functor indicates a contract failure (and will result in
  660. this library calling
  661. @RefFunc{boost::contract::precondition_failure}).
  662. This functor should capture variables by (constant) value, or better
  663. by (constant) reference to avoid extra copies.
  664. (This is a variadic macro parameter so it can contain commas not
  665. protected by round parenthesis.)
  666. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  667. Disable Contract Compilation},
  668. @RefSect{tutorial.constructors, Constructors}
  669. */
  670. #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...)
  671. #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS) // Not NO_CONSTRUCTORS here.
  672. // constructor_precondition.hpp already #included at top.
  673. #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \
  674. boost::contract::constructor_precondition< __VA_ARGS__ >
  675. #else
  676. #include <boost/preprocessor/tuple/eat.hpp>
  677. // constructor_precondition.hpp always #included at top of this file.
  678. #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \
  679. /* always use default ctor (i.e., do nothing) */ \
  680. boost::contract::constructor_precondition< __VA_ARGS__ >() \
  681. BOOST_PP_TUPLE_EAT(0)
  682. #endif
  683. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  684. /**
  685. Program contracts that can be completely disabled at compile-time for
  686. destructors.
  687. This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION},
  688. @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to
  689. specify postconditions, exception guarantees, and old value copies at body
  690. that can be completely disabled at compile-time for destructors (destructors
  691. cannot have preconditions, see
  692. @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}):
  693. @code
  694. class u {
  695. friend class boost::contract::access;
  696. BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile).
  697. BOOST_CONTRACT_ASSERT(...);
  698. ...
  699. })
  700. public:
  701. ~u() {
  702. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  703. BOOST_CONTRACT_DESTRUCTOR(this)
  704. // No `PRECONDITION` (destructors have no preconditions).
  705. BOOST_CONTRACT_OLD([&] { // Optional.
  706. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  707. ...
  708. })
  709. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  710. BOOST_CONTRACT_ASSERT(...);
  711. ...
  712. })
  713. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  714. BOOST_CONTRACT_ASSERT(...);
  715. ...
  716. })
  717. ; // Trailing `;` is required.
  718. ... // Destructor body.
  719. }
  720. ...
  721. };
  722. @endcode
  723. For optimization, this can be omitted for destructors that do not have
  724. postconditions and exception guarantees, within classes that have no
  725. invariants.
  726. @c BOOST_CONTRACT_DESTRUCTOR(obj) expands to code equivalent to the
  727. following (note that no code is generated when
  728. @RefMacro{BOOST_CONTRACT_NO_DESTRUCTORS} is defined):
  729. @code
  730. #ifndef BOOST_CONTRACT_NO_DESTRUCTORS
  731. boost::contract::check internal_var =
  732. boost::contract::destructor(obj)
  733. #endif
  734. @endcode
  735. Where:
  736. @arg <c><b>obj</b></c> is the object @c this from the scope of the
  737. enclosing destructor declaring the contract.
  738. Destructors check all class invariants, including static and
  739. volatile invariants (see @RefSect{tutorial.class_invariants,
  740. Class Invariants} and
  741. @RefSect{extras.volatile_public_functions,
  742. Volatile Public Functions}).
  743. (This is a variadic macro parameter so it can contain commas not
  744. protected by round parenthesis.)
  745. @arg <c><b>internal_var</b></c> is a variable name internally generated
  746. by this library (this name is unique but only on different line
  747. numbers so this macro cannot be expanded multiple times on the same
  748. line).
  749. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  750. Disable Contract Compilation},
  751. @RefSect{tutorial.destructors, Destructors}
  752. */
  753. #define BOOST_CONTRACT_DESTRUCTOR(...)
  754. #elif !defined(BOOST_CONTRACT_NO_DESTRUCTORS)
  755. #include <boost/contract/destructor.hpp>
  756. #include <boost/contract/check.hpp>
  757. #include <boost/contract/detail/name.hpp>
  758. #define BOOST_CONTRACT_DESTRUCTOR(...) \
  759. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  760. boost::contract::destructor(__VA_ARGS__)
  761. #else
  762. #define BOOST_CONTRACT_DESTRUCTOR(...) /* nothing */
  763. #endif
  764. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  765. /**
  766. Program contracts that can be completely disabled at compile-time for
  767. (non-public) functions.
  768. This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION},
  769. @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT},
  770. and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions,
  771. exception guarantees, and old value copies at body that can be completely
  772. disabled at compile-time for (non-public) functions:
  773. @code
  774. void f(...) {
  775. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  776. BOOST_CONTRACT_FUNCTION()
  777. BOOST_CONTRACT_PRECONDITION([&] { // Optional.
  778. BOOST_CONTRACT_ASSERT(...);
  779. ...
  780. })
  781. BOOST_CONTRACT_OLD([&] { // Optional.
  782. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  783. ...
  784. })
  785. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  786. BOOST_CONTRACT_ASSERT(...);
  787. ...
  788. })
  789. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  790. BOOST_CONTRACT_ASSERT(...);
  791. ...
  792. })
  793. ; // Trailing `;` is required.
  794. ... // Function body.
  795. }
  796. @endcode
  797. This can be used to program contracts for non-member functions but also for
  798. private and protected functions, lambda functions, loops, arbitrary blocks
  799. of code, etc.
  800. For optimization, this can be omitted for code that does not have
  801. preconditions, postconditions, and exception guarantees.
  802. @c BOOST_CONTRACT_FUNCTION() expands to code equivalent to the following
  803. (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_FUNCTIONS}
  804. is defined):
  805. @code
  806. #ifndef BOOST_CONTRACT_NO_FUNCTIONS
  807. boost::contract::check internal_var =
  808. boost::contract::function()
  809. #endif
  810. @endcode
  811. Where:
  812. @arg <c><b>internal_var</b></c> is a variable name internally generated
  813. by this library (this name is unique but only on different line
  814. numbers so this macro cannot be expanded multiple times on the same
  815. line).
  816. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  817. Disable Contract Compilation},
  818. @RefSect{tutorial.non_member_functions, Non-Member Functions},
  819. @RefSect{advanced.private_and_protected_functions,
  820. Private and Protected Functions},
  821. @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__,
  822. Lambdas\, Loops\, Code Blocks}
  823. */
  824. #define BOOST_CONTRACT_FUNCTION()
  825. #elif !defined(BOOST_CONTRACT_NO_FUNCTIONS)
  826. #include <boost/contract/function.hpp>
  827. #include <boost/contract/check.hpp>
  828. #include <boost/contract/detail/name.hpp>
  829. #define BOOST_CONTRACT_FUNCTION() \
  830. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  831. boost::contract::function()
  832. #else
  833. #include <boost/preprocessor/facilities/empty.hpp>
  834. #define BOOST_CONTRACT_FUNCTION() /* nothing */
  835. #endif
  836. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  837. /**
  838. Program contracts that can be completely disabled at compile-time for static
  839. public functions.
  840. This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION},
  841. @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT},
  842. and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions,
  843. exception guarantees, and old value copies at body that can be completely
  844. disabled at compile-time for static public functions:
  845. @code
  846. class u {
  847. friend class boost::contract::access;
  848. BOOST_CONTRACT_STATIC_INVARIANT({ // Optional (as for non-static).
  849. BOOST_CONTRACT_ASSERT(...);
  850. ...
  851. })
  852. public:
  853. static void f(...) {
  854. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  855. BOOST_CONTRACT_PUBLIC_FUNCTION(u)
  856. BOOST_CONTRACT_PRECONDITION([&] { // Optional.
  857. BOOST_CONTRACT_ASSERT(...);
  858. ...
  859. })
  860. BOOST_CONTRACT_OLD([&] { // Optional.
  861. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  862. ...
  863. })
  864. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  865. BOOST_CONTRACT_ASSERT(...);
  866. ...
  867. })
  868. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  869. BOOST_CONTRACT_ASSERT(...);
  870. ...
  871. })
  872. ; // Trailing `;` is required.
  873. ... // Function body.
  874. }
  875. ...
  876. };
  877. @endcode
  878. For optimization, this can be omitted for static public functions that do
  879. not have preconditions, postconditions and exception guarantees, within
  880. classes that have no static invariants.
  881. @c BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(class_type) expands to code
  882. equivalent to the following (note that no code is generated when
  883. @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined):
  884. @code
  885. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  886. boost::contract::check internal_var =
  887. boost::contract::public_function<class_type>()
  888. #endif
  889. @endcode
  890. Where:
  891. @arg <c><b>class_type</b></c> is the type of the class containing the
  892. static public function declaring the contract.
  893. (This is a variadic macro parameter so it can contain commas not
  894. protected by round parenthesis.)
  895. @arg <c><b>internal_var</b></c> is a variable name internally generated
  896. by this library (this name is unique but only on different line
  897. numbers so this macro cannot be expanded multiple times on the same
  898. line).
  899. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  900. Disable Contract Compilation},
  901. @RefSect{tutorial.static_public_functions, Static Public Functions}
  902. */
  903. #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...)
  904. /**
  905. Program contracts that can be completely disabled at compile-time for
  906. non-static public functions that do not override.
  907. This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION},
  908. @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT},
  909. and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions,
  910. exception guarantees, and old value copies at body that can be completely
  911. disabled at compile-time for non-static public functions (virtual or not,
  912. void or not) that do not override:
  913. @code
  914. class u {
  915. friend class boost::contract::access;
  916. BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile).
  917. BOOST_CONTRACT_ASSERT(...);
  918. ...
  919. })
  920. public:
  921. // Non-virtual (same if void).
  922. t f(...) {
  923. t result;
  924. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  925. BOOST_CONTRACT_PUBLIC_FUNCTION(this)
  926. BOOST_CONTRACT_PRECONDITION([&] { // Optional.
  927. BOOST_CONTRACT_ASSERT(...);
  928. ...
  929. })
  930. BOOST_CONTRACT_OLD([&] { // Optional.
  931. old_var = BOOST_CONTRACT_OLDOF(old_expr);
  932. ...
  933. })
  934. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  935. BOOST_CONTRACT_ASSERT(...);
  936. ...
  937. })
  938. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  939. BOOST_CONTRACT_ASSERT(...);
  940. ...
  941. })
  942. ; // Trailing `;` is required.
  943. ... // Function body (use `return result = return_expr`).
  944. }
  945. // Virtual and void.
  946. virtual void g(..., boost::contract::virtual_* v = 0) {
  947. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  948. BOOST_CONTRACT_PUBLIC_FUNCTION(v, this)
  949. ...
  950. BOOST_CONTRACT_OLD([&] { // Optional.
  951. old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
  952. ...
  953. })
  954. ...
  955. ; // Trailing `;` is required.
  956. ... // Function body.
  957. }
  958. // Virtual and non-void.
  959. virtual t h(..., boost::contract::virtual_* v = 0) {
  960. t result;
  961. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  962. BOOST_CONTRACT_PUBLIC_FUNCTION(v, result, this)
  963. ...
  964. BOOST_CONTRACT_OLD([&] { // Optional.
  965. old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
  966. ...
  967. })
  968. BOOST_CONTRACT_POSTCONDITION([&] (t const& result) { // Optional
  969. BOOST_CONTRACT_ASSERT(...);
  970. ...
  971. })
  972. ...
  973. ; // Trailing `;` is required.
  974. ... // Function body (use `return result = return_expr`).
  975. }
  976. ...
  977. };
  978. @endcode
  979. For optimization, this can be omitted for non-virtual public functions that
  980. do not have preconditions, postconditions and exception guarantees, within
  981. classes that have no invariants.
  982. Virtual public functions should always use
  983. @RefMacro{BOOST_CONTRACT_PUBLIC_FUNCTION} otherwise this library will not
  984. be able to correctly use them for subcontracting.
  985. This is an overloaded variadic macro and it can be used in the following
  986. different ways (note that no code is generated when
  987. @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined).
  988. 1\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(obj)</c> expands to code
  989. equivalent to the following (for non-virtual public functions that are
  990. not static and do not override, returning void or not):
  991. @code
  992. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  993. boost::contract::check internal_var =
  994. boost::contract::public_function(obj)
  995. #endif
  996. @endcode
  997. 2\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(v, obj)</c> expands to code
  998. equivalent to the following (for virtual public functions that do not
  999. override, returning void):
  1000. @code
  1001. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  1002. boost::contract::check internal_var =
  1003. boost::contract::public_function(v, obj)
  1004. #endif
  1005. @endcode
  1006. 3\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(v, r, obj)</c> expands to code
  1007. equivalent to the following (for virtual public functions that do not
  1008. override, not returning void):
  1009. @code
  1010. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  1011. boost::contract::check internal_var =
  1012. boost::contract::public_function(v, r, obj)
  1013. #endif
  1014. @endcode
  1015. Where (these are all variadic macro parameters so they can contain commas
  1016. not protected by round parenthesis):
  1017. @arg <c><b>v</b></c> is the extra parameter of type
  1018. @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
  1019. from the enclosing virtual public function declaring the contract.
  1020. @arg <c><b>r</b></c> is a reference to the return value of the enclosing
  1021. virtual public function declaring the contract.
  1022. This is usually a local variable declared by the enclosing virtual
  1023. public function just before the contract, but programmers must set
  1024. it to the actual value being returned by the function at each
  1025. @c return statement.
  1026. @arg <c><b>obj</b></c> is the object @c this from the scope of the
  1027. enclosing public function declaring the contract.
  1028. This object might be mutable, @c const, @c volatile, or
  1029. <c>const volatile</c> depending on the cv-qualifier of the enclosing
  1030. function (volatile public functions will check volatile class
  1031. invariants, see @RefSect{extras.volatile_public_functions,
  1032. Volatile Public Functions}).
  1033. @arg <c><b>internal_var</b></c> is a variable name internally generated
  1034. by this library (this name is unique but only on different line
  1035. numbers so this macro cannot be expanded multiple times on the same
  1036. line).
  1037. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  1038. Disable Contract Compilation},
  1039. @RefSect{tutorial.public_functions, Public Functions},
  1040. @RefSect{tutorial.virtual_public_functions,
  1041. Virtual Public Functions}
  1042. */
  1043. #define BOOST_CONTRACT_PUBLIC_FUNCTION(...)
  1044. /**
  1045. Program contracts that can be completely disabled at compile-time for
  1046. public function overrides.
  1047. This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION},
  1048. @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT},
  1049. and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions,
  1050. exception guarantees, and old value copies at body that can be completely
  1051. disabled at compile-time for public function overrides (virtual or not):
  1052. @code
  1053. class u
  1054. #define BASES private boost::contract::constructor_precondition<u>, \
  1055. public b, private w
  1056. : BASES
  1057. {
  1058. friend class boost::contract::access;
  1059. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  1060. #undef BASES
  1061. BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile).
  1062. BOOST_CONTRACT_ASSERT(...);
  1063. ...
  1064. })
  1065. BOOST_CONTRACT_OVERRIDES(f, g)
  1066. public:
  1067. // Override from `b::f`, and void.
  1068. void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
  1069. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  1070. BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_f)(
  1071. v, &u::f, this, a_1, ..., a_n)
  1072. BOOST_CONTRACT_PRECONDITION([&] { // Optional.
  1073. BOOST_CONTRACT_ASSERT(...);
  1074. ...
  1075. })
  1076. BOOST_CONTRACT_OLD([&] { // Optional.
  1077. old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
  1078. ...
  1079. })
  1080. BOOST_CONTRACT_POSTCONDITION([&] { // Optional.
  1081. BOOST_CONTRACT_ASSERT(...);
  1082. ...
  1083. })
  1084. BOOST_CONTRACT_EXCEPT([&] { // Optional.
  1085. BOOST_CONTRACT_ASSERT(...);
  1086. ...
  1087. })
  1088. ; // Trailing `;` is required.
  1089. ... // Function body.
  1090. }
  1091. // Override from `b::g`, and void.
  1092. t g(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
  1093. t result;
  1094. BOOST_CONTRACT_OLD_PTR(old_type)(old_var);
  1095. BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_g)(
  1096. v, result, &u::g, this, a_1, ..., a_n)
  1097. ...
  1098. BOOST_CONTRACT_OLD([&] { // Optional.
  1099. old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
  1100. ...
  1101. })
  1102. BOOST_CONTRACT_POSTCONDITION([&] (t const& result) { // Optional
  1103. BOOST_CONTRACT_ASSERT(...);
  1104. ...
  1105. })
  1106. ...
  1107. ; // Trailing `;` is required.
  1108. ... // Function body (use `return result = return_expr`).
  1109. }
  1110. ...
  1111. };
  1112. @endcode
  1113. Public function overrides should always use
  1114. @RefMacro{BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE} otherwise this library
  1115. will not be able to correctly use it for subcontracting.
  1116. This is an overloaded variadic macro and it can be used in the following
  1117. different ways (note that no code is generated when
  1118. @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined).
  1119. 1\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_type)(v, f, obj,
  1120. ...)</c> expands to code equivalent to the following (for public
  1121. function overrides that return void):
  1122. @code
  1123. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  1124. boost::contract::check internal_var = boost::contract::
  1125. public_function<override_type>(v, f, obj, ...)
  1126. #endif
  1127. @endcode
  1128. 2\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_type)(v, r, f, obj,
  1129. ...)</c> expands to code equivalent to the following (for public
  1130. function overrides that do not return void):
  1131. @code
  1132. #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
  1133. boost::contract::check internal_var = boost::contract::
  1134. public_function<override_type>(v, r, f, obj, ...)
  1135. #endif
  1136. @endcode
  1137. Where (these are all variadic macro parameters so they can contain commas
  1138. not protected by round parenthesis):
  1139. @arg <c><b>override_type</b></c> is the type
  1140. <c>override_<i>function-name</i></c> declared using the
  1141. @RefMacro{BOOST_CONTRACT_OVERRIDE} or related macros.
  1142. @arg <c><b>v</b></c> is the extra parameter of type
  1143. @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0
  1144. from the enclosing virtual public function declaring the contract.
  1145. @arg <c><b>r</b></c> is a reference to the return value of the enclosing
  1146. virtual public function declaring the contract.
  1147. This is usually a local variable declared by the enclosing virtual
  1148. public function just before the contract, but programmers must set
  1149. it to the actual value being returned by the function at each
  1150. @c return statement.
  1151. @arg <c><b>f</b></c> is a pointer to the enclosing public function
  1152. override declaring the contract.
  1153. @arg <c><b>obj</b></c> is the object @c this from the scope of the
  1154. enclosing public function declaring the contract.
  1155. This object might be mutable, @c const, @c volatile, or
  1156. <c>const volatile</c> depending on the cv-qualifier of the enclosing
  1157. function (volatile public functions will check volatile class
  1158. invariants, see @RefSect{extras.volatile_public_functions,
  1159. Volatile Public Functions}).
  1160. @arg <c><b>...</b></c> is a variadic macro parameter listing all the
  1161. arguments passed to the enclosing public function override declaring
  1162. the contract (by reference and in the order they appear in the
  1163. enclosing function declaration), but excluding the trailing
  1164. argument @c v.
  1165. @arg <c><b>internal_var</b></c> is a variable name internally generated
  1166. by this library (this name is unique but only on different line
  1167. numbers so this macro cannot be expanded multiple times on the same
  1168. line).
  1169. @see @RefSect{extras.disable_contract_compilation__macro_interface_,
  1170. Disable Contract Compilation},
  1171. @RefSect{tutorial.public_function_overrides__subcontracting_,
  1172. Public Function Overrides}
  1173. */
  1174. #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...)
  1175. #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
  1176. #include <boost/contract/public_function.hpp>
  1177. #include <boost/contract/check.hpp>
  1178. #include <boost/contract/detail/name.hpp>
  1179. #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...) \
  1180. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  1181. boost::contract::public_function< __VA_ARGS__ >()
  1182. #define BOOST_CONTRACT_PUBLIC_FUNCTION(...) \
  1183. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  1184. boost::contract::public_function(__VA_ARGS__)
  1185. #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...) \
  1186. boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \
  1187. boost::contract::public_function<__VA_ARGS__>
  1188. #else
  1189. #include <boost/preprocessor/tuple/eat.hpp>
  1190. #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...) /* nothing */
  1191. #define BOOST_CONTRACT_PUBLIC_FUNCTION(...) /* nothing */
  1192. #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...) BOOST_PP_TUPLE_EAT(0)
  1193. #endif
  1194. #endif // #include guard