]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | |
92f5a8d4 | 11 | Specify preconditions, old values copied at body, postconditions, and exception |
11fdf7f2 TL |
12 | guarantees |
13 | ||
92f5a8d4 | 14 | Preconditions, old values copied at body, postconditions, and exception |
11fdf7f2 TL |
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 | |
92f5a8d4 TL |
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. | |
11fdf7f2 TL |
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. | |
92f5a8d4 | 143 | This object is internally constructed by the library when users specify |
11fdf7f2 TL |
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 | ||
92f5a8d4 TL |
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 | |
11fdf7f2 TL |
157 | @RefSect{advanced.throw_on_failures__and__noexcept__, |
158 | Throw on Failure}). | |
11fdf7f2 TL |
159 | */ |
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. | |
92f5a8d4 | 191 | This object is internally constructed by the library when users specify |
11fdf7f2 TL |
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 | ||
92f5a8d4 TL |
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 | |
11fdf7f2 TL |
205 | @RefSect{advanced.throw_on_failures__and__noexcept__, |
206 | Throw on Failure}). | |
11fdf7f2 TL |
207 | */ |
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> | |
92f5a8d4 TL |
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_ } | |
11fdf7f2 TL |
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. | |
92f5a8d4 | 260 | This object is internally constructed by the library when users specify |
11fdf7f2 TL |
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 | |
92f5a8d4 TL |
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.) | |
11fdf7f2 TL |
274 | */ |
275 | template<typename VirtualResult = void> | |
276 | class specify_postcondition_except { // Privately copyable (as *). | |
277 | public: | |
278 | /** | |
279 | Destruct this object. | |
280 | ||
92f5a8d4 TL |
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 | |
11fdf7f2 TL |
284 | @RefSect{advanced.throw_on_failures__and__noexcept__, |
285 | Throw on Failure}). | |
11fdf7f2 TL |
286 | */ |
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 | |
92f5a8d4 | 293 | @c f() or @c f(result). |
11fdf7f2 TL |
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). | |
92f5a8d4 TL |
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). | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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_ } | |
11fdf7f2 TL |
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 | /** | |
92f5a8d4 | 365 | Allow to specify old values copied at body, postconditions, and exception |
11fdf7f2 TL |
366 | guarantees. |
367 | ||
92f5a8d4 | 368 | Allow to specify functors this library will call to copy old values at body, |
11fdf7f2 | 369 | check postconditions, and check exception guarantees. |
92f5a8d4 | 370 | This object is internally constructed by the library when users specify |
11fdf7f2 TL |
371 | contracts calling @RefFunc{boost::contract::function} and similar functions |
372 | (that is why this class does not have a public constructor). | |
373 | ||
92f5a8d4 | 374 | @see @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, |
11fdf7f2 TL |
375 | @RefSect{tutorial.postconditions, Postconditions}, |
376 | @RefSect{tutorial.exception_guarantees, Exception Guarantees} | |
377 | ||
378 | @tparam VirtualResult Return type of the enclosing function declaring the | |
92f5a8d4 TL |
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.) | |
11fdf7f2 TL |
385 | */ |
386 | template<typename VirtualResult = void> | |
387 | class specify_old_postcondition_except { // Privately copyable (as *). | |
388 | public: | |
389 | /** | |
390 | Destruct this object. | |
391 | ||
92f5a8d4 TL |
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 | |
11fdf7f2 TL |
395 | @RefSect{advanced.throw_on_failures__and__noexcept__, |
396 | Throw on Failure}). | |
11fdf7f2 TL |
397 | */ |
398 | ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} | |
399 | ||
400 | /** | |
92f5a8d4 | 401 | Allow to specify old values copied at body. |
11fdf7f2 TL |
402 | |
403 | It should often be sufficient to initialize old value pointers as soon as | |
404 | they are declared, without using this function (see | |
92f5a8d4 | 405 | @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). |
11fdf7f2 TL |
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 | ||
92f5a8d4 | 421 | @return After old values copied at body have been specified, the object |
11fdf7f2 TL |
422 | returned by this function allows to optionally specify |
423 | postconditions and exception guarantees. | |
424 | */ | |
425 | template<typename F> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
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 | |
92f5a8d4 | 440 | @c f() or @c f(result). |
11fdf7f2 TL |
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). | |
92f5a8d4 TL |
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). | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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_ } | |
11fdf7f2 TL |
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 | /** | |
92f5a8d4 | 517 | Allow to specify preconditions, old values copied at body, postconditions, and |
11fdf7f2 TL |
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. | |
92f5a8d4 | 522 | This object is internally constructed by the library when users specify |
11fdf7f2 TL |
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}, | |
92f5a8d4 | 527 | @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}, |
11fdf7f2 TL |
528 | @RefSect{tutorial.postconditions, Postconditions}, |
529 | @RefSect{tutorial.exception_guarantees, Exception Guarantees} | |
530 | ||
531 | @tparam VirtualResult Return type of the enclosing function declaring the | |
92f5a8d4 TL |
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.) | |
11fdf7f2 TL |
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 | ||
92f5a8d4 TL |
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 | |
11fdf7f2 TL |
553 | @RefSect{advanced.throw_on_failures__and__noexcept__, |
554 | Throw on Failure}). | |
11fdf7f2 TL |
555 | */ |
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 | |
92f5a8d4 | 572 | function allows to optionally specify old values copied at body, |
11fdf7f2 TL |
573 | postconditions, and exception guarantees. |
574 | */ | |
575 | template<typename F> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
583 | BOOST_CONTRACT_SPECIFY_PRECONDITION_IMPL_ |
584 | } | |
585 | ||
586 | /** | |
92f5a8d4 | 587 | Allow to specify old values copied at body. |
11fdf7f2 TL |
588 | |
589 | It should often be sufficient to initialize old value pointers as soon as | |
590 | they are declared, without using this function (see | |
92f5a8d4 | 591 | @RefSect{advanced.old_values_copied_at_body, Old Values Copied at Body}). |
11fdf7f2 TL |
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 | ||
92f5a8d4 | 607 | @return After old values copied at body have been specified, the object |
11fdf7f2 TL |
608 | returned by this functions allows to optionally specify |
609 | postconditions and exception guarantees. | |
610 | */ | |
611 | template<typename F> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
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 | |
92f5a8d4 | 626 | @c f() or @c f(result). |
11fdf7f2 TL |
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). | |
92f5a8d4 TL |
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). | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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 | ) { | |
11fdf7f2 TL |
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> | |
92f5a8d4 TL |
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_ } | |
11fdf7f2 TL |
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 |