@@ -48,6 +48,10 @@ class cdtor_checker
4848
4949 void check_out (void * const This)
5050 {
51+ // Under current usage, 'This' is the 'this'-pointer of a 'tester' object.
52+ // If it is NULL here, then something has already gone terribly wrong
53+ BOOST_TEST (This != NULL );
54+
5155 BOOST_TEST (objs.find (This) != objs.end ());
5256 objs.erase (This);
5357 }
@@ -66,6 +70,25 @@ struct tester
6670 mem.check_in (this );
6771 }
6872
73+ tester (int a0, int a1)
74+ {
75+ set_values (a0, a1, -1 , -1 );
76+
77+ mem.check_in (this );
78+ }
79+
80+ tester (int a0, const int & a1, int a2, const int a3, bool throw_except = false )
81+ {
82+ if (throw_except)
83+ {
84+ throw std::logic_error (" Deliberate constructor exception" );
85+ }
86+
87+ set_values (a0, a1, a2, a3);
88+
89+ mem.check_in (this );
90+ }
91+
6992 tester (const tester &)
7093 {
7194 mem.check_in (this );
@@ -75,6 +98,32 @@ struct tester
7598 {
7699 mem.check_out (this );
77100 }
101+
102+ int stored_a0;
103+ int stored_a1;
104+ int stored_a2;
105+ int stored_a3;
106+
107+ void set_values (int a0, int a1, int a2, int a3)
108+ {
109+ stored_a0 = a0;
110+ stored_a1 = a1;
111+ stored_a2 = a2;
112+ stored_a3 = a3;
113+ }
114+
115+ void check_values (int a0, int a1)
116+ {
117+ check_values (a0, a1, -1 , -1 );
118+ }
119+
120+ void check_values (int a0, int a1, int a2, int a3)
121+ {
122+ BOOST_TEST ( a0 == stored_a0 );
123+ BOOST_TEST ( a1 == stored_a1 );
124+ BOOST_TEST ( a2 == stored_a2 );
125+ BOOST_TEST ( a3 == stored_a3 );
126+ }
78127};
79128
80129// This is a wrapper around a UserAllocator. It just registers alloc/dealloc
@@ -113,6 +162,23 @@ std::set<char *> TrackAlloc<UserAllocator>::allocated_blocks;
113162
114163typedef TrackAlloc<boost::default_user_allocator_new_delete> track_alloc;
115164
165+ // This is a simple UserAllocator to allow coverage-testing of the codepath
166+ // where memory allocation fails.
167+ struct always_fails_allocation_alloc
168+ {
169+ typedef std::size_t size_type;
170+ typedef std::ptrdiff_t difference_type;
171+
172+ static char * malloc (const size_type /* bytes*/ )
173+ {
174+ return 0 ;
175+ }
176+
177+ static void free (char * const /* block*/ )
178+ {
179+ }
180+ };
181+
116182void test ()
117183{
118184 {
@@ -162,6 +228,53 @@ void test()
162228 }
163229 catch (const std::logic_error &) {}
164230 }
231+ #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
232+ for (int k=0 ; k < 5 ; ++k)
233+ {
234+ try
235+ {
236+ // The following constructions will raise an exception.
237+ pool.construct (k,2 *k,3 *k,4 *k,true );
238+ }
239+ catch (const std::logic_error &) {}
240+ }
241+ #endif
242+ }
243+
244+ {
245+ // Test the 'pool.construct' with 2 ctor parameters
246+ boost::object_pool<tester> pool;
247+ for (int i=0 ; i < 5 ; ++i)
248+ {
249+ tester * newItem = pool.construct (i, 2 *i);
250+ newItem->check_values (i, 2 *i);
251+ }
252+ }
253+
254+ #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
255+ {
256+ // Test the 'pool.construct' with 4 ctor parameters
257+ // Without variadic-templates, this functionality requires
258+ // that the end-user has run the 'detail/pool_construct.m4'
259+ // functionality to generate a larger set of 'construct()'
260+ // overloads. [see docs for object_pool::construct()]
261+ boost::object_pool<tester> pool;
262+ for (int i=0 ; i < 5 ; ++i)
263+ {
264+ tester * newItem = pool.construct (i, 2 *i, 3 *i, 5 *i);
265+ newItem->check_values (i, 2 *i, 3 *i, 5 *i);
266+ }
267+ }
268+ #endif
269+
270+ {
271+ // Test the case where memory allocation intentionally fails
272+ boost::object_pool<tester, always_fails_allocation_alloc> pool;
273+ BOOST_TEST ( pool.construct () == 0 );
274+ BOOST_TEST ( pool.construct (1 ,2 ) == 0 );
275+ #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
276+ BOOST_TEST ( pool.construct (1 ,2 ,3 ,4 ) == 0 );
277+ #endif
165278 }
166279}
167280
0 commit comments