]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/contract/core/constructor_precondition.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / contract / core / constructor_precondition.hpp
CommitLineData
11fdf7f2
TL
1
2#ifndef BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_HPP_
3#define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_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
11Program preconditions for constructors.
12*/
13
14// IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
15#include <boost/contract/core/config.hpp>
16#ifndef BOOST_CONTRACT_NO_PRECONDITIONS
17 #include <boost/contract/core/exception.hpp>
18 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
19 #include <boost/contract/detail/checking.hpp>
20 #endif
21#endif
22
23namespace boost { namespace contract {
24
25/**
26Program preconditions for constructors.
27
28This class must be the very first base of the class declaring the
29constructor for which preconditions are programmed (that way constructor
30arguments can be checked by preconditions even before they are used to
31initialize other base classes):
32
33@code
34 class u
35 #define BASES private boost::contract::constructor_precondition<u>, \
36 public b
37 : BASES
38 {
92f5a8d4
TL
39 friend class boost::contract::access;
40
41 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
11fdf7f2
TL
42 #undef BASES
43
44 public:
45 explicit u(unsigned x) :
46 boost::contract::constructor_precondition<u>([&] {
47 BOOST_CONTRACT_ASSERT(x != 0);
48 ...
49 }),
50 b(1.0 / float(x))
51 {
52 ...
53 }
54
55 ...
56 };
57@endcode
58
59User-defined classes should inherit privately from this class (to not alter the
60public interface of user-defined classes).
61In addition, this class should never be declared as a virtual base (because
62virtual bases are initialized only once across the entire inheritance hierarchy
63preventing preconditions of other base classes from being checked).
64
92f5a8d4
TL
65This class cannot be used this way in a @c union because unions cannot have base
66classes in C++.
67Instead, this class is used in a @c union to declare a local object within the
68constructor definition just before @RefFunc{boost::contract::constructor} is
69used (see @RefSect{extras.unions, Unions}).
11fdf7f2
TL
70
71@see @RefSect{tutorial.constructors, Constructors}
72
73@tparam Class The class type of the constructor for which preconditions are
74 being programmed.
75*/
76template<class Class>
77class constructor_precondition { // Copyable (has no data).
78public:
79 /**
80 Construct this object without specifying constructor preconditions.
81
82 This is implicitly called for those constructors of the contracted class
83 that do not specify preconditions.
84
92f5a8d4
TL
85 @note The implementation of this library is optimized so that calling this
86 default constructor should amount to negligible compile-time and
87 run-time overheads (likely to be optimized away completely by most
88 compilers).
11fdf7f2
TL
89 */
90 constructor_precondition() {}
91
92 /**
93 Construct this object specifying constructor preconditions.
94
95 @param f Nullary functor called by this library to check constructor
96 preconditions @c f().
97 Assertions within this functor call are usually programmed
98 using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown
99 by a call to this functor indicates a contract failure (and will
100 result in this library calling
101 @RefFunc{boost::contract::precondition_failure}).
102 This functor should capture variables by (constant) value, or
103 better by (constant) reference to avoid extra copies.
104 */
105 template<typename F>
106 explicit constructor_precondition(F const& f) {
107 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
108 try {
109 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
110 if(boost::contract::detail::checking::already()) return;
111 #ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
112 boost::contract::detail::checking k;
113 #endif
114 #endif
115 f();
116 } catch(...) { precondition_failure(from_constructor); }
117 #endif
118 }
119
120 // Default copy operations (so user's derived classes can be copied, etc.).
121};
122
123} } // namespace
124
125#endif // #include guard
126