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