Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / contract / check.hpp
1
2 #ifndef BOOST_CONTRACT_CHECK_HPP_
3 #define BOOST_CONTRACT_CHECK_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 RAII object that checks contracts.
12 */
13
14 #include <boost/contract/core/config.hpp>
15 #include <boost/contract/core/check_macro.hpp>
16 #include <boost/contract/core/specify.hpp>
17 #include <boost/contract/core/exception.hpp> // For set_... (if always in code).
18 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
19         defined(BOOST_CONTRACT_STATIC_LINK)
20     #include <boost/contract/detail/condition/cond_base.hpp>
21     #include <boost/contract/detail/auto_ptr.hpp>
22     #include <boost/contract/detail/debug.hpp>
23 #endif
24 #include <boost/contract/detail/check.hpp>
25 #include <boost/config.hpp>
26
27 /* PRIVATE */
28
29 /** @cond */
30
31 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
32         defined(BOOST_CONTRACT_STATIC_LINK)
33     #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) \
34         : cond_(const_cast<contract_type&>(contract).cond_.release()) \
35         { \
36             BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
37             cond_->initialize(); \
38         }
39 #else
40     #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) {}
41 #endif
42
43 /** @endcond */
44
45 /* CODE */
46
47 namespace boost { namespace contract {
48
49 /**
50 RAII object that checks the contracts.
51
52 In general, when this object is constructed it checks class invariants at entry,
53 preconditions, and makes old value copies at body.
54 When it is destructed, it checks class invariants at exist, postconditions, and
55 exception guarantees.
56 This object enforces the following (see
57 @RefSect{contract_programming_overview, Contract Programming Overview}):
58
59 @li Postconditions are checked only if the body does not throw an exception.
60 @li Exceptions guarantees are checked only if the body throws an exception.
61 @li Constructor entry never checks class invariants.
62 @li Destructor exit checks class invariants only if the body throws an
63 exception (even if destructors should usually not be programmed to throw
64 exceptions in C++ and they are implicitly declared @c noexcept since C++11).
65 @li Static invariants are always checked at entry and exit (and regardless of
66 the body throwing exceptions or not).
67
68 When used this way, this object is constructed and initialized to the return
69 value of one of the contract functions @RefFunc{boost::contract::function},
70 @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor},
71 or @RefFunc{boost::contract::public_function}.
72 In addition to that, this object can be constructed from a nullary functor when
73 it is used to program implementation checks.
74
75 @see    @RefSect{tutorial, Tutorial},
76         @RefSect{advanced.implementation_checks, Implementation Checks}
77 */
78 class check { // Copy ctor only (as move via ptr release).
79 public:
80     // NOTE: Unfortunately, Apple compilers define a `check(...)` macro that
81     // clashes with the name of this class. In the following code,
82     // BOOST_PREVENT_MACRO_SUBSTITUTION is used to workaround these name
83     // clashes. In user code, `check c = ...` syntax is typically used also
84     // avoiding clashes.
85
86     /**
87     Construct this object for implementation checks.
88
89     This can be used to program checks within implementation code (body, etc.).
90     This constructor is not declared @c explicit so initializations can use
91     assignment syntax @c =.
92     
93     @b Throws:  This can throw in case programmers specify contract failure
94                 handlers that throw exceptions instead of terminating the
95                 program (see
96                 @RefSect{advanced.throw_on_failures__and__noexcept__,
97                 Throw on Failure}).
98
99     @param f    Nullary functor that asserts implementation checks. @c f() will
100                 be called as soon as this object is constructed at the point it
101                 is declared within the implementation code (see
102                 @RefSect{advanced.implementation_checks,
103                 Implementation Checks}).
104     */
105     template<typename F> // Cannot check `if(f) ...` as f can be a lambda.
106     // f must be a valid callable object (not null func ptr, empty ftor, etc.
107     /* implicit */ check
108     /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
109             F const& f) {
110         BOOST_CONTRACT_DETAIL_CHECK({ f(); })
111     }
112
113     /**
114     Construct this object copying it from the specified one.
115
116     This object will check the contract, the copied-from object will not (i.e.,
117     contract check ownership is transferred from the copied object to the new
118     object being created by this constructor).
119
120     @param other    Copied-from object.
121     */
122     check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
123             check const& other)
124         #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
125                 defined(BOOST_CONTRACT_STATIC_LINK)
126             // Copy ctor moves cond_ pointer to dest.
127             : cond_(const_cast<check&>(other).cond_.release())
128         #endif
129     {}
130
131     /**
132     Construct this object to check the specified contract.
133
134     This checks class invariants at entry (if those were specified for the given
135     contract).
136     This constructor is not declared @c explicit so initializations can use
137     assignment syntax @c =.
138     
139     @b Throws:  This can throw in case programmers specify contract failure
140                 handlers that throw exceptions instead of terminating the
141                 program (see
142                 @RefSect{advanced.throw_on_failures__and__noexcept__,
143                 Throw on Failure}).
144
145     @param contract Contract to be checked (usually the return value of
146                     @RefFunc{boost::contract::function} or
147                     @RefFunc{boost::contract::public_function}).
148
149     @tparam VirtualResult   Return type of the enclosing function declaring the
150                             contract if that is either a virtual or an
151                             overriding public function, otherwise this is always
152                             @c void.
153                             (Usually this template parameter is automatically
154                             deduced by C++ and it does not need to be explicitly
155                             specified by programmers.)
156     */
157     template<typename VirtualResult>
158     /* implicit */ check
159     /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
160         specify_precondition_old_postcondition_except<VirtualResult> const&
161                 contract
162     )
163     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
164         BOOST_CONTRACT_CHECK_CTOR_DEF_(
165                 specify_precondition_old_postcondition_except<VirtualResult>)
166     #else
167         ;
168     #endif
169     
170     /**
171     Construct this object to check the specified contract.
172
173     This checks class invariants at entry and preconditions (if any of those
174     were specified for the given contract).
175     This constructor is not declared @c explicit so initializations can use
176     assignment syntax @c =.
177     
178     @b Throws:  This can throw in case programmers specify contract failure
179                 handlers that throw exceptions instead of terminating the
180                 program (see
181                 @RefSect{advanced.throw_on_failures__and__noexcept__,
182                 Throw on Failure}).
183
184     @param contract Contract to be checked (usually the return value of
185                     @RefFunc{boost::contract::function},
186                     @RefFunc{boost::contract::constructor},
187                     @RefFunc{boost::contract::destructor}, or
188                     @RefFunc{boost::contract::public_function}).
189
190     @tparam VirtualResult   Return type of the enclosing function declaring the
191                             contract if that is either a virtual or an
192                             overriding public function, otherwise this is always
193                             @c void.
194                             (Usually this template parameter is automatically
195                             deduced by C++ and it does not need to be explicitly
196                             specified by programmers.)
197     */
198     template<typename VirtualResult>
199     /* implicit */ check
200     /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
201             specify_old_postcondition_except<VirtualResult> const& contract)
202     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
203         BOOST_CONTRACT_CHECK_CTOR_DEF_(
204                 specify_old_postcondition_except<VirtualResult>)
205     #else
206         ;
207     #endif
208     
209     /**
210     Construct this object to check the specified contract.
211
212     This checks class invariants at entry and preconditions then it makes old
213     value copies at body (if any of those were specified for the given
214     contract).
215     This constructor is not declared @c explicit so initializations can use
216     assignment syntax @c =.
217     
218     @b Throws:  This can throw in case programmers specify contract failure
219                 handlers that throw exceptions instead of terminating te
220                 program (see
221                 @RefSect{advanced.throw_on_failures__and__noexcept__,
222                 Throw on Failure}).
223
224     @param contract Contract to be checked (usually the return value of
225                     @RefFunc{boost::contract::function},
226                     @RefFunc{boost::contract::constructor},
227                     @RefFunc{boost::contract::destructor}, or
228                     @RefFunc{boost::contract::public_function}).
229
230     @tparam VirtualResult   Return type of the enclosing function declaring the
231                             contract if that is either a virtual or an
232                             overriding public function, otherwise this is always
233                             @c void.
234                             (Usually this template parameter is automatically
235                             deduced by C++ and it does not need to be explicitly
236                             specified by programmers.)
237     */
238     template<typename VirtualResult>
239     /* implicit */ check
240     /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
241             specify_postcondition_except<VirtualResult> const& contract)
242     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
243         BOOST_CONTRACT_CHECK_CTOR_DEF_(
244                 specify_postcondition_except<VirtualResult>)
245     #else
246         ;
247     #endif
248     
249     /**
250     Construct this object to check the specified contract.
251
252     This checks class invariants at entry and preconditions then it makes old
253     value copies at body, plus the destructor of this object will also check
254     postconditions in this case (if any of those were specified for the given
255     contract).
256     This constructor is not declared @c explicit so initializations can use
257     assignment syntax @c =.
258     
259     @b Throws:  This can throw in case programmers specify contract failure
260                 handlers that throw exceptions instead of terminating the
261                 program (see
262                 @RefSect{advanced.throw_on_failures__and__noexcept__,
263                 Throw on Failure}).
264
265     @param contract Contract to be checked (usually the return value of
266                     @RefFunc{boost::contract::function},
267                     @RefFunc{boost::contract::constructor},
268                     @RefFunc{boost::contract::destructor}, or
269                     @RefFunc{boost::contract::public_function}).
270
271     @tparam VirtualResult   Return type of the enclosing function declaring the
272                             contract if that is either a virtual or an
273                             overriding public function, otherwise this is always
274                             @c void.
275                             (Usually this template parameter is automatically
276                             deduced by C++ and it does not need to be explicitly
277                             specified by programmers.)
278     */
279     /* implicit */ check
280     /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
281             specify_except const& contract)
282     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
283         BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_except)
284     #else
285         ;
286     #endif
287     
288     /**
289     Construct this object to check the specified contract.
290
291     This checks class invariants at entry and preconditions then it makes old
292     value copies at body, plus the destructor of this object will also check
293     postconditions and exception guarantees in this case (if any of those were
294     specified for the given contract).
295     This constructor is not declared @c explicit so initializations can use
296     assignment syntax @c =.
297     
298     @b Throws:  This can throw in case programmers specify contract failure
299                 handlers that throw exceptions instead of terminating the
300                 program (see
301                 @RefSect{advanced.throw_on_failures__and__noexcept__,
302                 Throw on Failure}).
303
304     @param contract Contract to be checked (usually the return value of
305                     @RefFunc{boost::contract::function},
306                     @RefFunc{boost::contract::constructor},
307                     @RefFunc{boost::contract::destructor}, or
308                     @RefFunc{boost::contract::public_function}).
309
310     @tparam VirtualResult   Return type of the enclosing function declaring the
311                             contract if that is either a virtual or an
312                             overriding public function, otherwise this is always
313                             @c void.
314                             (Usually this template parameter is automatically
315                             deduced by C++ and it does not need to be explicitly
316                             specified by programmers.)
317     */
318     /* implicit */ check
319     /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
320             specify_nothing const& contract)
321     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
322         BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_nothing)
323     #else
324         ;
325     #endif
326
327     /**
328     Destruct this object.
329
330     This checks class invariants at exit and either postconditions when the
331     enclosing function body did not throw an exception, or exception guarantees
332     when the function body threw an exception (if class invariants,
333     postconditions, and exception guarantees respectively were specified for the
334     enclosing class and the contract parameter given when constructing this
335     object).
336
337     @b Throws:  This can throw in case programmers specify contract failure
338                 handlers that throw exceptions instead of terminating the
339                 program (see
340                 @RefSect{advanced.throw_on_failures__and__noexcept__,
341                 Throw on Failure}).
342                 (This is declared @c noexcept(false) since C++11.)
343     */
344     ~check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ()
345         BOOST_NOEXCEPT_IF(false) /* allow auto_ptr dtor to throw */
346     {}
347
348 /** @cond */
349 private:
350     check& operator=(check const&); // Cannot copy outside of `check c = ...`.
351
352     #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
353             defined(BOOST_CONTRACT_STATIC_LINK)
354         boost::contract::detail::auto_ptr<boost::contract::detail::cond_base>
355                 cond_;
356     #endif
357 /** @endcond */
358 };
359
360 } } // namespace
361
362 #endif // #include guard
363