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