Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / contract / constructor.hpp
1
2 #ifndef BOOST_CONTRACT_CONSTRUCTOR_HPP_
3 #define BOOST_CONTRACT_CONSTRUCTOR_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 constructors.
12 */
13
14 #include <boost/contract/core/config.hpp>
15 #include <boost/contract/core/specify.hpp>
16 #include <boost/contract/core/access.hpp>
17 #include <boost/contract/core/constructor_precondition.hpp>
18 #if     !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
19         !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
20          defined(BOOST_CONTRACT_STATIC_LINK)
21     #include <boost/contract/detail/operation/constructor.hpp>
22 #endif
23
24 namespace boost { namespace contract {
25
26 /**
27 Program contracts for constructors.
28
29 This is used to specify postconditions, exception guarantees, old value copies
30 at body, and check class invariants for constructors (see
31 @RefClass{boost::contract::constructor_precondition} to specify preconditions
32 for constructors):
33
34 @code
35 class u {
36     friend class boost::contract:access;
37
38     void invariant() const { // Optional (as for static and volatile).
39         BOOST_CONTRACT_ASSERT(...);
40         ...
41     }
42
43 public:
44     u(...) {
45         boost::contract::old_ptr<old_type> old_var;
46         boost::contract::check c = boost::contract::constructor(this)
47             // No `.precondition` (use `constructor_precondition` instead).
48             .old([&] { // Optional.
49                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
50                 ...
51             })
52             .postcondition([&] { // Optional.
53                 BOOST_CONTRACT_ASSERT(...);
54                 ...
55             })
56             .except([&] { // Optional.
57                 BOOST_CONTRACT_ASSERT(...);
58                 ...
59             })
60         ;
61
62         ... // Constructor body.
63     }
64
65     ...
66 };
67 @endcode
68
69 For optimization, this can be omitted for constructors that do not have
70 postconditions and exception guarantees, within classes that have no invariants.
71
72 @see @RefSect{tutorial.constructors, Constructors}
73     
74 @param obj  The object @c this from the scope of the enclosing constructor
75             declaring the contract.
76             (Constructors check all class invariants, including static and
77             volatile invariants, see @RefSect{tutorial.class_invariants,
78             Class Invariants} and
79             @RefSect{extras.volatile_public_functions,
80             Volatile Public Functions}).
81
82 @tparam Class   The type of the class containing the constructor declaring the
83                 contract.
84                 (Usually this template parameter is automatically deduced by C++
85                 and it does not need to be explicitly specified by programmers.)
86
87 @return The result of this function must be assigned to a variable of type
88         @RefClass{boost::contract::check} declared explicitly (i.e., without
89         using C++11 @c auto declarations) and locally just before the code of
90         the constructor body (otherwise this library will generate a run-time
91         error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
92 */
93 template<class Class>
94 specify_old_postcondition_except<> constructor(Class* obj) {
95     // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
96     #if     !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \
97             !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
98              defined(BOOST_CONTRACT_STATIC_LINK)
99         return specify_old_postcondition_except<>(
100                 new boost::contract::detail::constructor<Class>(obj));
101     #else
102         return specify_old_postcondition_except<>();
103     #endif
104 }
105
106 } } // namespace
107
108 #endif // #include guard
109