Skip to content

Commit b45fd51

Browse files
Joe Herdmanjbherdman
authored andcommitted
Allow object_pool::construct() to use variadic template, if available.
1 parent f2b8fec commit b45fd51

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

include/boost/pool/object_pool.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,18 @@ class object_pool: protected pool<UserAllocator>
175175
//! detail/pool_construct.bat and detail/pool_construct.sh are also provided to call m4, defining NumberOfArguments
176176
//! to be their command-line parameter. See these files for more details.
177177
}
178+
#elif defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
179+
// When available, use variadic templates to avoid the older '.ipp'/'.m4' implementation
180+
template <typename... Args>
181+
element_type * construct(Args&&... args)
182+
{
183+
element_type* const ret = (malloc)();
184+
if (ret == 0)
185+
return ret;
186+
try { new (ret) element_type(std::forward<Args>(args)...); }
187+
catch (...) { (free)(ret); throw; }
188+
return ret;
189+
}
178190
#else
179191
// Include automatically-generated file for family of template construct() functions.
180192
// Copy .inc renamed .ipp to conform to Doxygen include filename expectations, PAB 12 Jan 11.

test/test_pool_alloc.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ struct tester
6666
mem.check_in(this);
6767
}
6868

69+
tester(int a0, int a1)
70+
{
71+
set_values(a0, a1, -1, -1);
72+
73+
mem.check_in(this);
74+
}
75+
76+
tester(int a0, const int& a1, int a2, const int a3)
77+
{
78+
set_values(a0, a1, a2, a3);
79+
80+
mem.check_in(this);
81+
}
82+
6983
tester(const tester &)
7084
{
7185
mem.check_in(this);
@@ -75,6 +89,32 @@ struct tester
7589
{
7690
mem.check_out(this);
7791
}
92+
93+
int stored_a0;
94+
int stored_a1;
95+
int stored_a2;
96+
int stored_a3;
97+
98+
void set_values(int a0, int a1, int a2, int a3)
99+
{
100+
stored_a0 = a0;
101+
stored_a1 = a1;
102+
stored_a2 = a2;
103+
stored_a3 = a3;
104+
}
105+
106+
void check_values(int a0, int a1)
107+
{
108+
check_values(a0, a1, -1, -1);
109+
}
110+
111+
void check_values(int a0, int a1, int a2, int a3)
112+
{
113+
BOOST_TEST( a0 == stored_a0 );
114+
BOOST_TEST( a1 == stored_a1 );
115+
BOOST_TEST( a2 == stored_a2 );
116+
BOOST_TEST( a3 == stored_a3 );
117+
}
78118
};
79119

80120
// This is a wrapper around a UserAllocator. It just registers alloc/dealloc
@@ -163,6 +203,32 @@ void test()
163203
catch(const std::logic_error &) {}
164204
}
165205
}
206+
207+
{
208+
// Test the 'pool.construct' with 2 ctor parameters
209+
boost::object_pool<tester> pool;
210+
for(int i=0; i < 5; ++i)
211+
{
212+
tester * newItem = pool.construct(i, 2*i);
213+
newItem->check_values(i, 2*i);
214+
}
215+
}
216+
217+
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
218+
{
219+
// Test the 'pool.construct' with 4 ctor parameters
220+
// Without variadic-templates, this functionality requires
221+
// that the end-user has run the 'detail/pool_construct.m4'
222+
// functionality to generate a larger set of 'construct()'
223+
// overloads. [see docs for object_pool::construct()]
224+
boost::object_pool<tester> pool;
225+
for(int i=0; i < 5; ++i)
226+
{
227+
tester * newItem = pool.construct(i, 2*i, 3*i, 5*i);
228+
newItem->check_values(i, 2*i, 3*i, 5*i);
229+
}
230+
}
231+
#endif
166232
}
167233

168234
void test_alloc()

0 commit comments

Comments
 (0)