Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / contract / public_function.hpp
1
2 #ifndef BOOST_CONTRACT_PUBLIC_FUNCTION_HPP_
3 #define BOOST_CONTRACT_PUBLIC_FUNCTION_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 Program contracts for public functions (including subcontracting).
12 The different overloads handle public functions that are static, virtual void,
13 virtual non-void, overriding void, and overriding non-void.
14 */
15
16 #include <boost/contract/core/config.hpp>
17 #include <boost/contract/core/specify.hpp>
18 #include <boost/contract/core/access.hpp>
19 #include <boost/contract/core/virtual.hpp>
20 /** @cond */
21 // Needed within macro expansions below instead of defined(...) (PRIVATE macro).
22 #if !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) || \
23         defined(BOOST_CONTRACT_STATIC_LINK)
24     #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 1
25 #else
26     #define BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ 0
27 #endif
28 /** @endcond */
29 #include <boost/contract/detail/decl.hpp>
30 #include <boost/contract/detail/tvariadic.hpp>
31 #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
32     #include <boost/contract/detail/operation/static_public_function.hpp>
33     #include <boost/contract/detail/operation/public_function.hpp>
34     #include <boost/contract/detail/type_traits/optional.hpp>
35     #include <boost/contract/detail/none.hpp>
36     #include <boost/function_types/result_type.hpp>
37     #include <boost/function_types/function_arity.hpp>
38     #include <boost/optional.hpp>
39     #include <boost/type_traits/remove_reference.hpp>
40     #include <boost/type_traits/is_same.hpp>
41     #include <boost/static_assert.hpp>
42     #include <boost/preprocessor/tuple/eat.hpp>
43 #endif
44 #if !BOOST_CONTRACT_DETAIL_TVARIADIC
45     #include <boost/preprocessor/repetition/repeat.hpp>
46     #include <boost/preprocessor/arithmetic/sub.hpp>
47     #include <boost/preprocessor/arithmetic/inc.hpp>
48 #endif
49 #include <boost/preprocessor/control/expr_iif.hpp>
50 #include <boost/preprocessor/control/iif.hpp>
51 #include <boost/preprocessor/facilities/empty.hpp>
52 #include <boost/preprocessor/punctuation/comma_if.hpp>
53
54 namespace boost { namespace contract {
55
56 // NOTE: Override and (optionally) VirtualResult allowed only when v is present
57 // because:
58 // * An overriding func must override a base func declared virtual so with
59 //   v extra param, thus the overriding func must also always have v (i.e.,
60 //   Override might be present only if v is also present). However, the first
61 //   appearing virtual func (e.g., in root class) will not override any
62 //   previously declared virtual func so does not need Override (i.e., Override
63 //   always optional).
64 //   Furthermore, F needs to be specified only together with Override.
65 // * VirtualResult is only used for virtual functions (i.e., VirtualResult might
66 //   be present only if v is also present).
67 //   However, VirtualResult is never specified, not even for virtual functions,
68 //   when the return type is void (i.e., VirtualResult always optional).
69
70 /**
71 Program contracts for static public functions.
72
73 This is used to specify preconditions, postconditions, exception guarantees, old
74 value copies at body, and check static class invariants for static public
75 functions:
76
77 @code
78 class u {
79     friend class boost::contract::access;
80
81     static void static_invariant() { // Optional (as for non-static).
82         BOOST_CONTRACT_ASSERT(...);
83         ...
84     }
85
86 public:
87     static void f(...) {
88         boost::contract::old_ptr<old_type> old_var;
89         boost::contract::check c = boost::contract::public_function<u>()
90             .precondition([&] { // Optional.
91                 BOOST_CONTRACT_ASSERT(...);
92                 ...
93             })
94             .old([&] { // Optional.
95                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
96                 ...
97             })
98             .postcondition([&] { // Optional.
99                 BOOST_CONTRACT_ASSERT(...);
100                 ...
101             })
102             .except([&] { // Optional.
103                 BOOST_CONTRACT_ASSERT(...);
104                 ...
105             })
106         ;
107
108         ... // Function body.
109     }
110     
111     ...
112 };
113 @endcode
114
115 For optimization, this can be omitted for static public functions that do not
116 have preconditions, postconditions and exception guarantees, within classes that
117 have no static invariants.
118
119 @see @RefSect{tutorial.static_public_functions, Static Public Functions}
120
121 @tparam Class   The type of the class containing the static public function
122                 declaring the contract.
123                 This template parameter must be explicitly specified for static
124                 public functions (because they have no object @c this so there
125                 is no function argument from which this type template parameter
126                 can be automatically deduced by C++).
127
128 @return The result of this function must be assigned to a variable of type
129         @RefClass{boost::contract::check} declared explicitly (i.e., without
130         using C++11 @c auto declarations) and locally just before the code of
131         the static public function body (otherwise this library will generate a
132         run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
133 */
134 template<class Class>
135 specify_precondition_old_postcondition_except<> public_function() {
136     #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
137         return specify_precondition_old_postcondition_except<>(
138             new boost::contract::detail::static_public_function<Class>());
139     #else
140         return specify_precondition_old_postcondition_except<>();
141     #endif
142 }
143
144 /**
145 Program contracts for public functions that are not static, not virtual, and do
146 not not override.
147
148 This is used to specify preconditions, postconditions, exception guarantees, old
149 value copies at body, and check class invariants for public functions that are
150 not static, not virtual, and do not override:
151
152 @code
153 class u {
154     friend class boost::contract::access;
155
156     void invariant() const { // Optional (as for static and volatile).
157         BOOST_CONTRACT_ASSERT(...);
158         ...
159     }
160
161 public:
162     void f(...) {
163         boost::contract::old_ptr<old_type> old_var;
164         boost::contract::check c = boost::contract::public_function(this)
165             .precondition([&] { // Optional.
166                 BOOST_CONTRACT_ASSERT(...);
167                 ...
168             })
169             .old([&] { // Optional.
170                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
171                 ...
172             })
173             .postcondition([&] { // Optional.
174                 BOOST_CONTRACT_ASSERT(...);
175                 ...
176             })
177             .except([&] { // Optional.
178                 BOOST_CONTRACT_ASSERT(...);
179                 ...
180             })
181         ;
182
183         ... // Function body.
184     }
185     
186     ...
187 };
188 @endcode
189
190 For optimization, this can be omitted for public functions that do not have
191 preconditions, postconditions and exception guarantees, within classes that have
192 no invariants.
193
194 @see @RefSect{tutorial.public_functions, Public Functions}
195
196 @param obj  The object @c this from the scope of the enclosing public function
197             declaring the contract.
198             This object might be mutable, @c const, @c volatile, or
199             <c>const volatile</c> depending on the cv-qualifier of the enclosing
200             function (volatile public functions will check volatile class
201             invariants, see
202             @RefSect{extras.volatile_public_functions,
203             Volatile Public Functions}).
204
205 @tparam Class   The type of the class containing the public function declaring
206                 the contract.
207                 (Usually this template parameter is automatically deduced by C++
208                 and it does not need to be explicitly specified by programmers.)
209
210 @return The result of this function must be assigned to a variable of type
211         @RefClass{boost::contract::check} declared explicitly (i.e., without
212         using C++11 @c auto declarations) and locally just before the code of
213         the public function body (otherwise this library will generate a
214         run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
215 */
216 template<class Class>
217 specify_precondition_old_postcondition_except<> public_function(Class* obj) {
218     #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_
219         return specify_precondition_old_postcondition_except<>(
220             new boost::contract::detail::public_function<
221                 boost::contract::detail::none,
222                 boost::contract::detail::none,
223                 boost::contract::detail::none,
224                 Class
225                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
226                         BOOST_CONTRACT_MAX_ARGS)
227                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
228                     BOOST_CONTRACT_MAX_ARGS,
229                     boost::contract::detail::none
230                 )
231             >(
232                 static_cast<boost::contract::virtual_*>(0),
233                 obj,
234                 boost::contract::detail::none::value()
235                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(
236                         BOOST_CONTRACT_MAX_ARGS)
237                 BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1,
238                     BOOST_CONTRACT_MAX_ARGS,
239                     boost::contract::detail::none::value()
240                 )
241             )
242         );
243     #else
244         return specify_precondition_old_postcondition_except<>();
245     #endif
246 }
247
248 /** @cond */
249
250 // For non-static, virtual, and non-overriding public functions (PRIVATE macro).
251 #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_( \
252         has_virtual_result) \
253     template< \
254         BOOST_PP_EXPR_IIF(has_virtual_result, typename VirtualResult) \
255         BOOST_PP_COMMA_IF(has_virtual_result) \
256         class Class \
257     > \
258     specify_precondition_old_postcondition_except< \
259             BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)> \
260     public_function( \
261         virtual_* v \
262         BOOST_PP_COMMA_IF(has_virtual_result) \
263         BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult& r) \
264         , Class* obj \
265     ) { \
266         BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
267             /* no F... so cannot enforce contracted F returns VirtualResult */ \
268             return (specify_precondition_old_postcondition_except< \
269                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
270                 new boost::contract::detail::public_function< \
271                     boost::contract::detail::none, \
272                     BOOST_PP_IIF(has_virtual_result, \
273                         VirtualResult \
274                     , \
275                         boost::contract::detail::none \
276                     ), \
277                     boost::contract::detail::none, \
278                     Class \
279                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
280                             BOOST_CONTRACT_MAX_ARGS) \
281                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
282                         BOOST_CONTRACT_MAX_ARGS, \
283                         boost::contract::detail::none \
284                     ) \
285                 >( \
286                     v, \
287                     obj, \
288                     BOOST_PP_IIF(has_virtual_result, \
289                         r \
290                     , \
291                         boost::contract::detail::none::value() \
292                     ) \
293                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA( \
294                             BOOST_CONTRACT_MAX_ARGS) \
295                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(1, \
296                         BOOST_CONTRACT_MAX_ARGS, \
297                         boost::contract::detail::none::value() \
298                     ) \
299                 ) \
300             )); \
301         , \
302             return specify_precondition_old_postcondition_except< \
303                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
304         ) \
305     }
306
307 /** @endcond */
308     
309 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
310     /**
311     Program contracts for void virtual public functions that do not override.
312
313     This is used to specify preconditions, postconditions, exception guarantees,
314     old value copies at body, and check class invariants for public functions
315     that are virtual, do not override, and return @c void:
316
317     @code
318     class u {
319         friend class boost::contract::access;
320
321         void invariant() const { // Optional (as for static and volatile).
322             BOOST_CONTRACT_ASSERT(...);
323             ...
324         }
325
326     public:
327         void f(..., boost::contract::virtual_* v = 0) {
328             boost::contract::old_ptr<old_type> old_var;
329             boost::contract::check c = boost::contract::public_function(v, this)
330                 .precondition([&] { // Optional.
331                     BOOST_CONTRACT_ASSERT(...);
332                     ...
333                 })
334                 .old([&] { // Optional.
335                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
336                     ...
337                 })
338                 .postcondition([&] { // Optional.
339                     BOOST_CONTRACT_ASSERT(...);
340                     ...
341                 })
342                 .except([&] { // Optional.
343                     BOOST_CONTRACT_ASSERT(...);
344                     ...
345                 })
346             ;
347
348             ... // Function body.
349         }
350         
351         ...
352     };
353     @endcode
354
355     A virtual public function should always call
356     @RefFunc{boost::contract::public_function} otherwise this library will not
357     be able to correctly use it for subcontracting.
358
359     @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
360     
361     @param v    The trailing parameter of type
362                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
363                 @c 0 from the enclosing virtual public function.
364     @param obj  The object @c this from the scope of the enclosing virtual
365                 public function declaring the contract.
366                 This object might be mutable, @c const, @c volatile, or
367                 <c>const volatile</c> depending on the cv-qualifier of the
368                 enclosing function (volatile public functions will check
369                 volatile class invariants, see
370                 @RefSect{extras.volatile_public_functions,
371                 Volatile Public Functions}).
372
373     @tparam Class   The type of the class containing the virtual public function
374                     declaring the contract.
375                     (Usually this template parameter is automatically deduced by
376                     C++ and it does not need to be explicitly specified by
377                     programmers.)
378     
379     @return The result of this function must be assigned to a variable of type
380             @RefClass{boost::contract::check} declared explicitly (i.e., without
381             using C++11 @c auto declarations) and locally just before the code
382             of the public function body (otherwise this library will generate a
383             run-time error, see
384             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
385     */
386     template<class Class>
387     specify_precondition_old_postcondition_except<> public_function(
388             virtual_* v, Class* obj);
389     
390     /**
391     Program contracts for non-void virtual public functions that do not
392     override.
393
394     This is used to specify preconditions, postconditions, exception guarantees,
395     old value copies at body, and check class invariants for public functions
396     that are virtual, do not override, and do not return @c void:
397     
398     @code
399     class u {
400         friend class boost::contract::access;
401
402         void invariant() const { // Optional (as for static and volatile).
403             BOOST_CONTRACT_ASSERT(...);
404             ...
405         }
406
407     public:
408         t f(..., boost::contract::virtual_* v = 0) {
409             t result;
410             boost::contract::old_ptr<old_type> old_var;
411             boost::contract::check c = boost::contract::public_function(
412                     v, result, this)
413                 .precondition([&] { // Optional.
414                     BOOST_CONTRACT_ASSERT(...);
415                     ...
416                 })
417                 .old([&] { // Optional.
418                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
419                     ...
420                 })
421                 .postcondition([&] (t const& result) { // Optional.
422                     BOOST_CONTRACT_ASSERT(...);
423                     ...
424                 })
425                 .except([&] { // Optional.
426                     BOOST_CONTRACT_ASSERT(...);
427                     ...
428                 })
429             ;
430
431             ... // Function body (use `return result = return_expr`).
432         }
433         
434         ...
435     };
436     @endcode
437
438     A virtual public function should always call
439     @RefFunc{boost::contract::public_function} otherwise this library will not
440     be able to correctly use it for subcontracting.
441
442     @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}
443     
444     @param v    The trailing parameter of type
445                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
446                 @c 0 from the enclosing virtual public function.
447     @param r    A reference to the return value of the enclosing virtual public
448                 function declaring the contract.
449                 This is usually a local variable declared by the enclosing
450                 virtual public function just before the contract, but
451                 programmers must set it to the actual value being returned by
452                 the function at each @c return statement.
453     @param obj  The object @c this from the scope of the enclosing virtual
454                 public function declaring the contract.
455                 This object might be mutable, @c const, @c volatile, or
456                 <c>const volatile</c> depending on the cv-qualifier of the
457                 enclosing function (volatile public functions will check
458                 volatile class invariants, see
459                 @RefSect{extras.volatile_public_functions,
460                 Volatile Public Functions}).
461     
462     @tparam VirtualResult   This type must be the same as, or compatible with,
463                             the return type of the enclosing virtual public
464                             function declaring the contract (this library might
465                             not be able to generate a compile-time error if
466                             these types mismatch, but in general that will cause
467                             run-time errors or undefined behaviour).
468                             Alternatively,
469                             <c>boost::optional<<i>return-type</i>></c> can also
470                             be used (see
471                             @RefSect{advanced.optional_return_values,
472                             Optional Return Values}).
473                             (Usually this template parameter is automatically
474                             deduced by C++ and it does not need to be explicitly
475                             specified by programmers.)
476     @tparam Class   The type of the class containing the virtual public function
477                     declaring the contract.
478                     (Usually this template parameter is automatically deduced by
479                     C++ and it does not need to be explicitly specified by
480                     programmers.)
481     
482     @return The result of this function must be assigned to a variable of type
483             @RefClass{boost::contract::check} declared explicitly (i.e., without
484             using C++11 @c auto declarations) and locally just before the code
485             of the public function body (otherwise this library will generate a
486             run-time error, see
487             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
488     */
489     template<typename VirtualResult, class Class>
490     specify_precondition_old_postcondition_except<VirtualResult>
491     public_function(virtual_* v, VirtualResult& r, Class* obj);
492 #else
493     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
494             /* has_virtual_result = */ 0)
495     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_NO_OVERRIDE_(
496             /* has_virtual_result = */ 1)
497 #endif
498
499 /** @cond */
500
501 // For non-static, virtual, and overriding public functions (PRIVATE macro).
502 #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_( \
503         z, arity, arity_compl, has_virtual_result) \
504     BOOST_CONTRACT_DETAIL_DECL_OVERRIDING_PUBLIC_FUNCTION_Z(z, \
505         arity, /* is_friend = */ 0, has_virtual_result, \
506         Override, VirtualResult, F, Class, Args, \
507         v, r, /* f */ BOOST_PP_EMPTY(), obj, args \
508     ) { \
509         BOOST_PP_IIF(BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_, \
510             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
511                 /* assert not strictly necessary as compilation will fail */ \
512                 /* anyways, but helps limiting cryptic compiler's errors */ \
513                 BOOST_STATIC_ASSERT_MSG( \
514                     /* -2 for both `this` and `virtual_*` extra parameters */ \
515                     ( \
516                         boost::function_types::function_arity<F>::value - 2 \
517                     == \
518                         BOOST_CONTRACT_DETAIL_TVARIADIC_SIZEOF(arity, Args) \
519                     ), \
520                     "missing one or more arguments for specified function" \
521                 ); \
522             } \
523             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
524                 /* assert consistency of F's result type and VirtualResult */ \
525                 BOOST_PP_IIF(has_virtual_result, \
526                     BOOST_STATIC_ASSERT_MSG \
527                 , \
528                     BOOST_PP_TUPLE_EAT(2) \
529                 )( \
530                     (boost::is_same< \
531                         typename boost::remove_reference<typename boost:: \
532                                 function_types::result_type<F>::type>::type, \
533                         typename boost::contract::detail:: \
534                                 remove_value_reference_if_optional< \
535                             VirtualResult \
536                         >::type \
537                     >::value), \
538                     "mismatching result type for specified function" \
539                 ); \
540             } \
541             { /* extra scope paren to expand STATIC_STATIC emu on same line */ \
542                 /* assert this so lib can check and enforce override */ \
543                 BOOST_STATIC_ASSERT_MSG( \
544                     boost::contract::access::has_base_types<Class>::value, \
545                     "enclosing class missing 'base-types' typedef" \
546                 ); \
547             } \
548             return (specify_precondition_old_postcondition_except< \
549                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>( \
550                 new boost::contract::detail::public_function< \
551                     Override, \
552                     BOOST_PP_IIF(has_virtual_result, \
553                         VirtualResult \
554                     , \
555                         boost::contract::detail::none \
556                     ), \
557                     F, \
558                     Class \
559                     BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
560                     BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, Args) \
561                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
562                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
563                             boost::contract::detail::none) \
564                 >( \
565                     v, \
566                     obj, \
567                     BOOST_PP_IIF(has_virtual_result, \
568                         r \
569                     , \
570                         boost::contract::detail::none::value() \
571                     ) \
572                     BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
573                     BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, args) \
574                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
575                     BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
576                             boost::contract::detail::none::value()) \
577                 ) \
578             )); \
579         , \
580             return specify_precondition_old_postcondition_except< \
581                     BOOST_PP_EXPR_IIF(has_virtual_result, VirtualResult)>(); \
582         ) \
583     }
584
585 /** @endcond */
586
587 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
588     /**
589     Program contracts for void public functions overrides (virtual or not).
590
591     This is used to specify preconditions, postconditions, exception guarantees,
592     old value copies at body, and check class invariants for public function
593     overrides (virtual or not) that return @c void:
594     
595     @code
596     class u
597         #define BASES private boost::contract::constructor_precondition<u>, \
598                 public b, private w
599         : BASES
600     {
601         friend class boost::contract::access;
602
603         typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
604         #undef BASES
605
606         void invariant() const { // Optional (as for static and volatile).
607             BOOST_CONTRACT_ASSERT(...);
608             ...
609         }
610
611         BOOST_CONTRACT_OVERRIDES(f)
612
613     public:
614         // Override from `b::f`.
615         void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
616             boost::contract::old_ptr<old_type> old_var;
617             boost::contract::check c = boost::contract::public_function<
618                     override_f>(v, &u::f, this, a_1, ..., a_n)
619                 .precondition([&] { // Optional.
620                     BOOST_CONTRACT_ASSERT(...);
621                     ...
622                 })
623                 .old([&] { // Optional.
624                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
625                     ...
626                 })
627                 .postcondition([&] { // Optional.
628                     BOOST_CONTRACT_ASSERT(...);
629                     ...
630                 })
631                 .except([&] { // Optional.
632                     BOOST_CONTRACT_ASSERT(...);
633                     ...
634                 })
635             ;
636
637             ... // Function body.
638         }
639         
640         ...
641     };
642     @endcode
643
644     A public function override should always call
645     @RefFunc{boost::contract::public_function} otherwise this library will not
646     be able to correctly use it for subcontracting.
647
648     @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
649             Public Function Overrides}
650     
651     @param v    The trailing parameter of type
652                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
653                 @c 0 from the enclosing public function override.
654     @param f    A pointer to the enclosing public function override declaring
655                 the contract (but see @RefSect{advanced.function_overloads,
656                 Function Overloads}).
657     @param obj  The object @c this from the scope of the enclosing public
658                 function override declaring the contract.
659                 This object might be mutable, @c const, @c volatile, or
660                 <c>const volatile</c> depending on the cv-qualifier of the
661                 enclosing function (volatile public functions will check
662                 volatile class invariants, see
663                 @RefSect{extras.volatile_public_functions,
664                 Volatile Public Functions}).
665     @param args All arguments passed to the enclosing public function override
666                 declaring the contract (by reference and in the order they
667                 appear in the enclosing function declaration), but excluding the
668                 trailing argument @c v.
669
670     @tparam Override    The type trait <c>override_<i>function-name</i></c>
671                         declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
672                         related macros.
673                         This template parameter must be explicitly specified
674                         (because there is no function argument from which it can
675                         be automatically deduced by C++).
676     @tparam F   The function pointer type of the enclosing public function
677                 override declaring the contract.
678                 (Usually this template parameter is automatically deduced by
679                 C++ and it does not need to be explicitly specified by
680                 programmers.)
681     @tparam Class   The type of the class containing the virtual public function
682                     declaring the contract.
683                     (Usually this template parameter is automatically deduced by
684                     C++ and it does not need to be explicitly specified by
685                     programmers.)
686     @tparam Args    The types of all parameters passed to the enclosing public
687                     function override declaring the contract, but excluding the
688                     trailing parameter type <c>boost::contract::virtual_*</c>.
689                     On compilers that do not support variadic templates, this
690                     library internally implements this function using
691                     preprocessor meta-programming (in this case, the maximum
692                     number of supported arguments is defined by
693                     @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
694                     (Usually these template parameters are automatically deduced
695                     by C++ and they do not need to be explicitly specified by
696                     programmers.)
697
698     @return The result of this function must be assigned to a variable of type
699             @RefClass{boost::contract::check} declared explicitly (i.e., without
700             using C++11 @c auto declarations) and locally just before the code
701             of the public function body (otherwise this library will generate a
702             run-time error, see
703             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
704     */
705     template<class Override, typename F, class Class, typename... Args>
706     specify_precondition_old_postcondition_except<> public_function(
707             virtual_* v, F f, Class* obj, Args&... args);
708
709     /**
710     Program contracts for non-void public functions overrides (virtual or not).
711
712     This is used to specify preconditions, postconditions, exception guarantees,
713     old value copies at body, and check class invariants for public function
714     overrides (virtual or not) that do not return @c void:
715     
716     @code
717     class u
718         #define BASES private boost::contract::constructor_precondition<u>, \
719                 public b, private w
720         : BASES
721     {
722         friend class boost::contract::access;
723
724         typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
725         #undef BASES
726
727         void invariant() const { // Optional (as for static and volatile).
728             BOOST_CONTRACT_ASSERT(...);
729             ...
730         }
731
732         BOOST_CONTRACT_OVERRIDES(f)
733
734     public:
735         // Override from `b::f`.
736         t f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) {
737             t result;
738             boost::contract::old_ptr<old_type> old_var;
739             boost::contract::check c = boost::contract::public_function<
740                     override_f>(v, result, &u::f, this, a_1, ..., a_n)
741                 .precondition([&] { // Optional.
742                     BOOST_CONTRACT_ASSERT(...);
743                     ...
744                 })
745                 .old([&] { // Optional.
746                     old_var = BOOST_CONTRACT_OLDOF(v, old_expr);
747                     ...
748                 })
749                 .postcondition([&] (t const& result) { // Optional.
750                     BOOST_CONTRACT_ASSERT(...);
751                     ...
752                 })
753                 .except([&] { // Optional.
754                     BOOST_CONTRACT_ASSERT(...);
755                     ...
756                 })
757             ;
758
759             ... // Function body (use `return result = return_expr`).
760         }
761         
762         ...
763     };
764     @endcode
765
766     A public function override should always call
767     @RefFunc{boost::contract::public_function} otherwise this library will not
768     be able to correctly use it for subcontracting.
769
770     @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
771             Public Function Overrides}
772     
773     @param v    The trailing parameter of type
774                 @RefClass{boost::contract::virtual_}<c>*</c> and default value
775                 @c 0 from the enclosing public function override.
776     @param r    A reference to the return value of the enclosing public function
777                 override declaring the contract.
778                 This is usually a local variable declared by the enclosing
779                 public function override just before the contract, but
780                 programmers must set it to the actual value being returned by
781                 the function at each @c return statement.
782     @param f    A pointer to the enclosing public function override declaring
783                 the contract (but see @RefSect{advanced.function_overloads,
784                 Function Overloads}).
785     @param obj  The object @c this from the scope of the enclosing public
786                 function override declaring the contract.
787                 This object might be mutable, @c const, @c volatile, or
788                 <c>const volatile</c> depending on the cv-qualifier of the
789                 enclosing function (volatile public functions will check
790                 volatile class invariants, see
791                 @RefSect{extras.volatile_public_functions,
792                 Volatile Public Functions}).
793     @param args All arguments passed to the enclosing public function override
794                 declaring the contract (by reference and in the order they
795                 appear in the enclosing function declaration), but excluding the
796                 trailing argument @c v.
797
798     @tparam Override    The type trait <c>override_<i>function-name</i></c>
799                         declared using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or
800                         related macros.
801                         This template parameter must be explicitly specified
802                         (because there is no function argument from which it can
803                         be automatically deduced by C++).
804     @tparam VirtualResult   This type must be the same as, or compatible with,
805                             the return type of the enclosing public function
806                             override declaring the contract (this library might
807                             not be able to generate a compile-time error if
808                             these types mismatch, but in general that will cause
809                             run-time errors or undefined behaviour).
810                             Alternatively,
811                             <c>boost::optional<<i>return-type</i>></c> can also
812                             be used (see
813                             @RefSect{advanced.optional_return_values,
814                             Optional Return Values}).
815                             (Usually this template parameter is automatically
816                             deduced by C++ and it does not need to be explicitly
817                             specified by programmers.)
818     @tparam F   The function pointer type of the enclosing public function
819                 override declaring the contract.
820                 (Usually this template parameter is automatically deduced by
821                 C++ and it does not need to be explicitly specified by
822                 programmers.)
823     @tparam Class   The type of the class containing the virtual public function
824                     declaring the contract.
825                     (Usually this template parameter is automatically deduced by
826                     C++ and it does not need to be explicitly specified by
827                     programmers.)
828     @tparam Args    The types of all parameters passed to the enclosing public
829                     function override declaring the contract, but excluding the
830                     trailing parameter type <c>boost::contract::virtual_*</c>.
831                     On compilers that do not support variadic templates, this
832                     library internally implements this function using
833                     preprocessor meta-programming (in this case, the maximum
834                     number of supported arguments is defined by
835                     @RefMacro{BOOST_CONTRACT_MAX_ARGS}).
836                     (Usually these template parameters are automatically deduced
837                     by C++ and they do not need to be explicitly specified by
838                     programmers.)
839
840     @return The result of this function must be assigned to a variable of type
841             @RefClass{boost::contract::check} declared explicitly (i.e., without
842             using C++11 @c auto declarations) and locally just before the code
843             of the public function body (otherwise this library will generate a
844             run-time error, see
845             @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
846     */
847     template<class Override, typename VirtualResult, typename F, class Class,
848             typename... Args>
849     specify_precondition_old_postcondition_except<VirtualResult>
850     public_function(virtual_* v, VirtualResult& r, F f, Class* obj,
851             Args&... args);
852
853 #elif BOOST_CONTRACT_DETAIL_TVARIADIC
854     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
855             /* arity_compl = */ ~, /* has_virtual_result = */ 0)
856     BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(1, /* arity = */ ~,
857             /* arity_compl = */ ~, /* has_virtual_result = */ 1)
858
859 #else
860     /* PRIVATE */
861
862     #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_( \
863             z, arity, unused) \
864         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, arity, \
865                 BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), ~)
866     
867     #define BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDES_(z, \
868             arity, arity_compl, unused) \
869         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
870                 arity, arity_compl, /* has_virtual_result = */ 0) \
871         BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_Z_(z, \
872                 arity, arity_compl, /* has_virtual_result = */ 1)
873
874     /* CODE */
875
876     BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS),
877             BOOST_CONTRACT_PUBLIC_FUNCTION_VIRTUAL_OVERRIDE_ARITY_, ~)
878 #endif
879
880 } } // namespace
881
882 #endif // #include guard
883