]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | |
2 | #ifndef BOOST_CONTRACT_VIRTUAL_HPP_ | |
3 | #define BOOST_CONTRACT_VIRTUAL_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 | Handle virtual public functions with contracts (for subcontracting). | |
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_CONDITIONS | |
17 | #include <boost/contract/detail/decl.hpp> | |
18 | #endif | |
19 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
20 | #include <boost/any.hpp> | |
21 | #endif | |
22 | #ifndef BOOST_CONTRACT_NO_OLDS | |
23 | #include <boost/shared_ptr.hpp> | |
24 | #include <queue> | |
25 | #endif | |
26 | ||
27 | namespace boost { namespace contract { | |
28 | ||
29 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
30 | namespace detail { | |
31 | BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, | |
32 | /* is_friend = */ 0, OO, RR, FF, CC, AArgs); | |
33 | } | |
34 | #endif | |
35 | ||
36 | /** | |
37 | Type of extra function parameter to handle contracts for virtual public | |
38 | functions (for subcontracting). | |
39 | ||
40 | Virtual public functions (and therefore also public function overrides) | |
41 | declaring contracts using this library must specify an extra function parameter | |
92f5a8d4 | 42 | at the very end of their parameter list. |
11fdf7f2 | 43 | This parameter must be a pointer to this class and it must have default value |
92f5a8d4 TL |
44 | @c 0 or @c nullptr (this extra parameter is often named @c v in this |
45 | documentation, but any name can be used): | |
46 | ||
47 | @code | |
48 | class u { | |
49 | public: | |
50 | virtual void f(int x, boost::contract::virtual_* v = 0) { // Declare `v`. | |
51 | ... // Contract declaration (which will use `v`) and function body. | |
52 | } | |
53 | ||
54 | ... | |
55 | }; | |
56 | @endcode | |
11fdf7f2 TL |
57 | |
58 | In practice this extra parameter does not alter the calling interface of the | |
59 | enclosing function declaring the contract because it is always the very last | |
60 | parameter and it has a default value (so it can always be omitted when users | |
61 | call the function). | |
62 | This extra parameter must be passed to | |
63 | @RefFunc{boost::contract::public_function}, @RefMacro{BOOST_CONTRACT_OLDOF}, and | |
64 | all other operations of this library that accept a pointer to | |
65 | @RefClass{boost::contract::virtual_}. | |
66 | A part from that, this class is not intended to be directly used by programmers | |
67 | (and that is why this class does not have any public member and it is not | |
68 | copyable). | |
69 | ||
70 | @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}, | |
71 | @RefSect{tutorial.public_function_overrides__subcontracting_, | |
72 | Public Function Overrides} | |
73 | */ | |
74 | class virtual_ { // Non-copyable (see below) to avoid copy queue, stack, etc. | |
75 | /** @cond */ | |
76 | private: // No public API (so users cannot use it directly by mistake). | |
77 | ||
78 | // No boost::noncopyable to avoid its overhead when contracts disabled. | |
79 | virtual_(virtual_&); | |
80 | virtual_& operator=(virtual_&); | |
81 | ||
82 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
83 | enum action_enum { | |
84 | // virtual_ always held/passed as ptr so nullptr used for user call. | |
85 | no_action, | |
86 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
87 | check_entry_inv, | |
88 | #endif | |
89 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
90 | check_pre, | |
91 | #endif | |
92 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
93 | check_exit_inv, | |
94 | #endif | |
95 | #ifndef BOOST_CONTRACT_NO_OLDS | |
96 | // For outside .old(...). | |
97 | push_old_init_copy, | |
98 | // pop_old_init_copy as static function below. | |
99 | // For inside .old(...). | |
100 | call_old_ftor, | |
101 | push_old_ftor_copy, | |
102 | pop_old_ftor_copy, | |
103 | #endif | |
104 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
105 | check_post, | |
106 | #endif | |
107 | #ifndef BOOST_CONTRACT_NO_EXCEPTS | |
108 | check_except, | |
109 | #endif | |
110 | }; | |
111 | #endif | |
112 | ||
113 | #ifndef BOOST_CONTRACT_NO_OLDS | |
114 | // Not just an enum value because the logical combination of two values. | |
115 | inline static bool pop_old_init_copy(action_enum a) { | |
116 | return | |
117 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
118 | a == check_post | |
119 | #endif | |
120 | #if !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ | |
121 | !defined(BOOST_CONTRACT_NO_EXCEPTS) | |
122 | || | |
123 | #endif | |
124 | #ifndef BOOST_CONTRACT_NO_EXCEPTS | |
125 | a == check_except | |
126 | #endif | |
127 | ; | |
128 | } | |
129 | #endif | |
130 | ||
131 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
132 | explicit virtual_(action_enum a) : | |
133 | action_(a) | |
134 | , failed_(false) | |
135 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
136 | , result_type_name_() | |
137 | , result_optional_() | |
138 | #endif | |
139 | {} | |
140 | #endif | |
141 | ||
142 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
143 | action_enum action_; | |
144 | bool failed_; | |
145 | #endif | |
146 | #ifndef BOOST_CONTRACT_NO_OLDS | |
147 | std::queue<boost::shared_ptr<void> > old_init_copies_; | |
148 | std::queue<boost::shared_ptr<void> > old_ftor_copies_; | |
149 | #endif | |
150 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
151 | boost::any result_ptr_; // Result for virtual and overriding functions. | |
152 | char const* result_type_name_; | |
153 | bool result_optional_; | |
154 | #endif | |
155 | ||
156 | // Friends (used to limit library's public API). | |
157 | #ifndef BOOST_CONTRACT_NO_OLDS | |
158 | friend bool copy_old(virtual_*); | |
159 | friend class old_pointer; | |
160 | #endif | |
161 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
162 | BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1, | |
163 | /* is_friend = */ 1, OO, RR, FF, CC, AArgs); | |
164 | #endif | |
165 | /** @endcond */ | |
166 | }; | |
167 | ||
168 | } } // namespace | |
169 | ||
170 | #endif // #include guard | |
171 |