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