Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / contract / detail / operation / public_function.hpp
1
2 #ifndef BOOST_CONTRACT_DETAIL_PUBLIC_FUNCTION_HPP_
3 #define BOOST_CONTRACT_DETAIL_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 #include <boost/contract/core/virtual.hpp>
11 #include <boost/contract/core/exception.hpp>
12 #include <boost/contract/core/config.hpp>
13 #include <boost/contract/core/virtual.hpp>
14 #include <boost/contract/detail/condition/cond_subcontracting.hpp>
15 #include <boost/contract/detail/tvariadic.hpp>
16 #include <boost/contract/detail/exception.hpp>
17 #if     !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
18         !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
19         !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
20         !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
21         !defined(BOOST_CONTRACT_NO_EXCEPTS))
22     #include <boost/contract/detail/checking.hpp>
23 #endif
24 #if     !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
25         !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
26         !defined(BOOST_CONTRACT_NO_EXCEPTS)
27     #include <boost/config.hpp>
28 #endif
29 #if     !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
30         !defined(BOOST_CONTRACT_NO_EXCEPTS)
31     #include <exception>
32 #endif
33
34 namespace boost { namespace contract { namespace detail {
35
36 template<
37     class O, typename VR, typename F, class C
38     BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
39     BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
40 >
41 class public_function : // Non-copyable base.
42     public cond_subcontracting<
43         O, VR, F, C
44         BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
45         BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1, BOOST_CONTRACT_MAX_ARGS, Args)
46     >
47 {
48 public:
49     explicit public_function(
50         boost::contract::virtual_* v, C* obj, VR& r
51         BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
52         BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(1,
53                 BOOST_CONTRACT_MAX_ARGS, Args, &, args)
54     ) :
55         cond_subcontracting<
56             O, VR, F, C
57             BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
58             BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
59                     BOOST_CONTRACT_MAX_ARGS, Args)
60         >(
61             boost::contract::from_function, v, obj, r
62             BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(BOOST_CONTRACT_MAX_ARGS)
63             BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(1,
64                     BOOST_CONTRACT_MAX_ARGS, args)
65         )
66     {}
67
68 private:
69     #if     !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
70             !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
71             !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
72             !defined(BOOST_CONTRACT_NO_EXCEPTS)
73         void init() /* override */ {
74             #if     !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
75                     !defined(BOOST_CONTRACT_NO_EXCEPTS)
76                 this->init_subcontracted_old();
77             #endif
78             if(!this->base_call()) {
79                 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
80                     if(checking::already()) return;
81                 #endif
82                 { // Acquire checking guard.
83                     #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
84                         checking k;
85                     #endif
86                     #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
87                         this->check_subcontracted_entry_inv();
88                     #endif
89                     #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
90                         #ifndef \
91   BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION
92                             this->check_subcontracted_pre();
93                             } // Release checking guard (after pre check).
94                         #else
95                             } // Release checking guard (before pre check).
96                             this->check_subcontracted_pre();
97                         #endif
98                     #else
99                         } // Release checking guard.
100                     #endif
101                 #ifndef BOOST_CONTRACT_NO_OLDS
102                     this->copy_subcontracted_old();
103                 #endif
104             } else {
105                 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
106                     this->check_subcontracted_entry_inv();
107                 #endif
108                 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
109                     this->check_subcontracted_pre();
110                 #endif
111                 #ifndef BOOST_CONTRACT_NO_OLDS
112                     this->copy_subcontracted_old();
113                 #endif
114                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
115                     this->check_subcontracted_exit_inv();
116                 #endif
117                 if(uncaught_exception()) {
118                     #ifndef BOOST_CONTRACT_NO_EXCEPTS
119                         this->check_subcontracted_except();
120                     #endif
121                 } else {
122                     #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
123                         this->check_subcontracted_post();
124                     #endif
125                 }
126             }
127         }
128     #endif
129
130 public:
131     #if     !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
132             !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
133             !defined(BOOST_CONTRACT_NO_EXCEPTS)
134         ~public_function() BOOST_NOEXCEPT_IF(false) {
135             this->assert_initialized();
136             if(!this->base_call()) {
137                 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
138                     if(checking::already()) return;
139                     checking k;
140                 #endif
141
142                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
143                     this->check_subcontracted_exit_inv();
144                 #endif
145                 if(uncaught_exception()) {
146                     #ifndef BOOST_CONTRACT_NO_EXCEPTS
147                         this->check_subcontracted_except();
148                     #endif
149                 } else {
150                     #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
151                         this->check_subcontracted_post();
152                     #endif
153                 }
154             }
155         }
156     #endif
157 };
158
159 } } } // namespace
160
161 #endif // #include guard
162