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 their parameter list. 43 This parameter must be a pointer to this class and it must have default value 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 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. pop_old_init_copy(action_enum a)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 virtual_(action_enum a)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 172