1 // (C) Copyright Gennadiy Rozental 2005-2008. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 // See http://www.boost.org/libs/test for the library home page. 7 // 8 // File : $RCSfile$ 9 // 10 // Version : $Revision: 54633 $ 11 // 12 // Description : Facilities to perform exception safety_tests 13 // *************************************************************************** 14 15 #ifndef BOOST_TEST_MOCK_OBJECT_HPP_112205GER 16 #define BOOST_TEST_MOCK_OBJECT_HPP_112205GER 17 18 // Boost.Test 19 #include <boost/test/detail/config.hpp> 20 #include <boost/test/interaction_based.hpp> 21 22 // Boost 23 #include <boost/preprocessor/punctuation/comma.hpp> 24 25 #include <boost/test/detail/suppress_warnings.hpp> 26 27 //____________________________________________________________________________// 28 29 namespace boost { 30 31 namespace itest { 32 33 // ************************************************************************** // 34 // ************** mock_object_base ************** // 35 // ************************************************************************** // 36 37 class mock_object_base { 38 public: mock_object_base()39 mock_object_base() {} 40 41 template<typename T1> mock_object_base(T1 const &)42 mock_object_base( T1 const& ) {} 43 44 template<typename T1, typename T2> mock_object_base(T1 const &,T2 const &)45 mock_object_base( T1 const&, T2 const& ) {} 46 47 template<typename T1, typename T2, typename T3> mock_object_base(T1 const &,T2 const &,T3 const &)48 mock_object_base( T1 const&, T2 const&, T3 const& ) {} 49 50 template<typename T1, typename T2, typename T3, typename T4> mock_object_base(T1 const &,T2 const &,T3 const &,T4 const &)51 mock_object_base( T1 const&, T2 const&, T3 const&, T4 const& ) {} 52 53 template<typename T1, typename T2, typename T3, typename T4, typename T5> mock_object_base(T1 const &,T2 const &,T3 const &,T4 const &,T5 const &)54 mock_object_base( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) {} 55 }; 56 57 // ************************************************************************** // 58 // ************** mock_object implementation helpers ************** // 59 // ************************************************************************** // 60 61 #define MO_OP_IMPL( op, descr, ret ) \ 62 BOOST_ITEST_SCOPE( mock_object::operator op ); \ 63 BOOST_ITEST_EPOINT( descr ); \ 64 return ret \ 65 /**/ 66 67 #define MO_UNARY_OP( op, descr ) \ 68 self_type const& operator op() const \ 69 { \ 70 MO_OP_IMPL( op, descr, prototype() ); \ 71 } \ 72 /**/ 73 74 #define MO_UNARY_BOOL_OP( op, descr ) \ 75 bool operator op() const \ 76 { \ 77 MO_OP_IMPL( op, descr, (!!BOOST_ITEST_DPOINT()) ); \ 78 } \ 79 /**/ 80 81 #define MO_BINARY_OP( op, descr ) \ 82 template<int i1, typename Base1,int i2, typename Base2> \ 83 inline mock_object<i1,Base1> const& \ 84 operator op( mock_object<i1,Base1> const& mo, \ 85 mock_object<i2,Base2> const& ) \ 86 { \ 87 MO_OP_IMPL( op, descr, mo ); \ 88 } \ 89 \ 90 template<int i, typename Base, typename T> \ 91 inline mock_object<i,Base> const& \ 92 operator op( mock_object<i,Base> const& mo, T const& ) \ 93 { \ 94 MO_OP_IMPL( op, descr, mo ); \ 95 } \ 96 \ 97 template<int i, typename Base, typename T> \ 98 inline mock_object<i,Base> const& \ 99 operator op( T const&, mock_object<i,Base> const& mo ) \ 100 { \ 101 MO_OP_IMPL( op, descr, mo ); \ 102 } \ 103 /**/ 104 105 #define MO_BINARY_BOOL_OP( op, descr ) \ 106 template<int i1, typename Base1,int i2, typename Base2> \ 107 inline bool \ 108 operator op( mock_object<i1,Base1> const&, \ 109 mock_object<i2,Base2> const& ) \ 110 { \ 111 MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \ 112 } \ 113 \ 114 template<int i, typename Base, typename T> \ 115 inline bool \ 116 operator op( mock_object<i,Base> const&, T const& ) \ 117 { \ 118 MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \ 119 } \ 120 \ 121 template<int i, typename Base, typename T> \ 122 inline bool \ 123 operator op( T const&, mock_object<i,Base> const& ) \ 124 { \ 125 MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \ 126 } \ 127 /**/ 128 129 // ************************************************************************** // 130 // ************** mock_object ************** // 131 // ************************************************************************** // 132 133 template<int i = 0, typename Base=mock_object_base> 134 class mock_object; 135 136 template<int i, typename Base> 137 class mock_object : public Base { 138 // Private typeefs 139 typedef mock_object<i,Base> self_type; nonnullboost::itest::mock_object::dummy140 struct dummy { void nonnull() {}; }; 141 typedef void (dummy::*safe_bool)(); 142 143 // prototype constructor mock_object(dummy *)144 mock_object( dummy* ) {} 145 146 public: prototype()147 static mock_object& prototype() 148 { 149 static mock_object p( reinterpret_cast<dummy*>(0) ); 150 return p; 151 } 152 153 // Constructors mock_object()154 mock_object() 155 { 156 BOOST_ITEST_SCOPE( mock_object::mock_object ); 157 BOOST_ITEST_EPOINT( "Mock object default constructor" ); 158 } 159 160 template<typename T1> mock_object(T1 const & arg1)161 mock_object( T1 const& arg1 ) 162 : mock_object_base( arg1 ) 163 { 164 BOOST_ITEST_SCOPE( mock_object::mock_object ); 165 BOOST_ITEST_EPOINT( "Mock object constructor" ); 166 } 167 168 template<typename T1, typename T2> mock_object(T1 const & arg1,T2 const & arg2)169 mock_object( T1 const& arg1, T2 const& arg2 ) 170 : mock_object_base( arg1, arg2 ) 171 { 172 BOOST_ITEST_SCOPE( mock_object::mock_object ); 173 BOOST_ITEST_EPOINT( "Mock object constructor" ); 174 } 175 176 template<typename T1, typename T2, typename T3> mock_object(T1 const & arg1,T2 const & arg2,T3 const & arg3)177 mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3 ) 178 : mock_object_base( arg1, arg2, arg3 ) 179 { 180 BOOST_ITEST_SCOPE( mock_object::mock_object ); 181 BOOST_ITEST_EPOINT( "Mock object constructor" ); 182 } 183 184 template<typename T1, typename T2, typename T3, typename T4> mock_object(T1 const & arg1,T2 const & arg2,T3 const & arg3,T4 const & arg4)185 mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 ) 186 : mock_object_base( arg1, arg2, arg3, arg4 ) 187 { 188 BOOST_ITEST_SCOPE( mock_object::mock_object ); 189 BOOST_ITEST_EPOINT( "Mock object constructor" ); 190 } 191 192 template<typename T1, typename T2, typename T3, typename T4, typename T5> mock_object(T1 const & arg1,T2 const & arg2,T3 const & arg3,T4 const & arg4,T5 const & arg5)193 mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4, T5 const& arg5 ) 194 : mock_object_base( arg1, arg2, arg3, arg4, arg5 ) 195 { 196 BOOST_ITEST_SCOPE( mock_object::mock_object ); 197 BOOST_ITEST_EPOINT( "Mock object constructor" ); 198 } 199 mock_object(mock_object const &)200 mock_object( mock_object const& ) 201 { 202 BOOST_ITEST_SCOPE( mock_object::mock_object ); 203 BOOST_ITEST_EPOINT( "Mock object copy constructor" ); 204 } 205 206 // assignment operator =(mock_object const &) const207 self_type const& operator =( mock_object const& ) const 208 { 209 MO_OP_IMPL( =, "Copy assignment", prototype() ); 210 } 211 212 template <typename T> operator =(T const &) const213 self_type const& operator =( T const& ) const 214 { 215 MO_OP_IMPL( =, "Copy assignment", prototype() ); 216 } 217 218 // Unary operators 219 MO_UNARY_BOOL_OP( !, "Logical NOT operator" ) 220 MO_UNARY_OP( &, "Address-of operator" ) 221 MO_UNARY_OP( ~, "One's complement operator" ) 222 MO_UNARY_OP( *, "Pointer dereference" ) 223 MO_UNARY_OP( +, "Unary plus" ) 224 225 // Increment and Decrement 226 MO_UNARY_OP( ++, "Prefix increment" ) 227 MO_UNARY_OP( --, "Prefix decrement" ) operator ++(int) const228 self_type const& operator ++(int) const 229 { 230 MO_OP_IMPL( ++, "Postfix increment", prototype() ); 231 } operator --(int) const232 self_type const& operator --(int) const 233 { 234 MO_OP_IMPL( --, "Postfix decrement", prototype() ); 235 } 236 237 // Bool context convertion operator safe_bool() const238 operator safe_bool() const 239 { 240 MO_OP_IMPL( safe_bool, "Bool context conversion", 241 (BOOST_ITEST_DPOINT() ? 0 : &dummy::nonnull) ); 242 } 243 244 // Function-call operators operator ()() const245 self_type const& operator ()() const 246 { 247 MO_OP_IMPL( (), "0-arity function-call", prototype() ); 248 } 249 template<typename T1> operator ()(T1 const & arg1) const250 self_type const& operator ()( T1 const& arg1 ) const 251 { 252 MO_OP_IMPL( (), "1-arity function-call", prototype() ); 253 } 254 template<typename T1, typename T2> operator ()(T1 const &,T2 const &) const255 self_type const& operator ()( T1 const&, T2 const& ) const 256 { 257 MO_OP_IMPL( (), "2-arity function-call", prototype() ); 258 } 259 template<typename T1, typename T2, typename T3> operator ()(T1 const &,T2 const &,T3 const &) const260 self_type const& operator ()( T1 const&, T2 const&, T3 const& ) const 261 { 262 MO_OP_IMPL( (), "3-arity function-call", prototype() ); 263 } 264 template<typename T1, typename T2, typename T3, typename T4> operator ()(T1 const &,T2 const &,T3 const &,T4 const &) const265 self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const& ) const 266 { 267 MO_OP_IMPL( (), "4-arity function-call", prototype() ); 268 } 269 template<typename T1, typename T2, typename T3, typename T4, typename T5> operator ()(T1 const &,T2 const &,T3 const &,T4 const &,T5 const &) const270 self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) const 271 { 272 MO_OP_IMPL( (), "5-arity function-call", prototype() ); 273 } 274 275 // Substripting 276 template<typename T> operator [](T const &) const277 self_type const& operator []( T const& ) const 278 { 279 MO_OP_IMPL( [], "Substripting", prototype() ); 280 } 281 282 // Class member access operator ->() const283 self_type const* operator->() const 284 { 285 MO_OP_IMPL( ->, "Class member access", this ); 286 } 287 }; 288 289 // !! MO_BINARY_OP( BOOST_PP_COMMA(), "Comma operator" ) 290 291 MO_BINARY_BOOL_OP( !=, "Inequality" ) 292 MO_BINARY_OP( %, "Modulus" ) 293 MO_BINARY_OP( %=, "Modulus/assignment" ) 294 MO_BINARY_OP( &, "Bitwise AND" ) 295 MO_BINARY_BOOL_OP( &&, "Logical AND" ) 296 MO_BINARY_OP( &=, "Bitwise AND/assignment" ) 297 MO_BINARY_OP( *, "Multiplication" ) 298 MO_BINARY_OP( *=, "Multiplication/assignment" ) 299 MO_BINARY_OP( +, "Addition" ) 300 MO_BINARY_OP( +=, "Addition/assignment" ) 301 //MO_BINARY_OP( -, "Subtraction" ) 302 MO_BINARY_OP( -=, "Subtraction/assignment" ) 303 MO_BINARY_OP( ->*, "Pointer-to-member selection" ) 304 MO_BINARY_OP( /, "Division" ) 305 MO_BINARY_OP( /=, "Division/assignment" ) 306 MO_BINARY_BOOL_OP( <, "Less than" ) 307 MO_BINARY_OP( <<=, "Left shift/assignment" ) 308 MO_BINARY_BOOL_OP( <=, "Less than or equal to" ) 309 MO_BINARY_BOOL_OP( ==, "Equality" ) 310 MO_BINARY_BOOL_OP( >, "Greater than" ) 311 MO_BINARY_BOOL_OP( >=, "Greater than or equal to" ) 312 MO_BINARY_OP( >>=, "Right shift/assignment" ) 313 MO_BINARY_OP( ^, "Exclusive OR" ) 314 MO_BINARY_OP( ^=, "Exclusive OR/assignment" ) 315 MO_BINARY_OP( |, "Bitwise inclusive OR" ) 316 MO_BINARY_OP( |=, "Bitwise inclusive OR/assignment" ) 317 MO_BINARY_BOOL_OP( ||, "Logical OR" ) 318 319 MO_BINARY_OP( <<, "Left shift" ) 320 MO_BINARY_OP( >>, "Right shift" ) 321 322 } // namespace itest 323 324 } // namespace boost 325 326 #include <boost/test/detail/enable_warnings.hpp> 327 328 #endif // BOOST_TEST_MOCK_OBJECT_HPP_112205GER 329