]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/contract/check.hpp
77e459b865c396bbf73017ddb4e8dcc8db7378ec
[ceph.git] / ceph / src / boost / 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