Skip to content

Commit

Permalink
Allow object_pool::construct() to use variadic template, if available.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Herdman committed Sep 6, 2019
1 parent 8edafbe commit 7f9a0ba
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/boost/pool/object_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ class object_pool: protected pool<UserAllocator>
//! detail/pool_construct.bat and detail/pool_construct.sh are also provided to call m4, defining NumberOfArguments
//! to be their command-line parameter. See these files for more details.
}
#elif defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
// When available, use variadic templates to avoid the older '.ipp'/'.m4' implementation
template <typename... Args>
element_type * construct(Args&&... args)
{
element_type* const ret = (malloc)();
if (ret == 0)
return ret;
try { new (ret) element_type(std::forward<Args>(args)...); }
catch (...) { (free)(ret); throw; }
return ret;
}
#else
// Include automatically-generated file for family of template construct() functions.
// Copy .inc renamed .ipp to conform to Doxygen include filename expectations, PAB 12 Jan 11.
Expand Down
66 changes: 66 additions & 0 deletions test/test_pool_alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ struct tester
mem.check_in(this);
}

tester(int a0, int a1)
{
set_values(a0, a1, -1, -1);

mem.check_in(this);
}

tester(int a0, const int& a1, int a2, const int a3)
{
set_values(a0, a1, a2, a3);

mem.check_in(this);
}

tester(const tester &)
{
mem.check_in(this);
Expand All @@ -75,6 +89,32 @@ struct tester
{
mem.check_out(this);
}

int stored_a0;
int stored_a1;
int stored_a2;
int stored_a3;

void set_values(int a0, int a1, int a2, int a3)
{
stored_a0 = a0;
stored_a1 = a1;
stored_a2 = a2;
stored_a3 = a3;
}

void check_values(int a0, int a1)
{
check_values(a0, a1, -1, -1);
}

void check_values(int a0, int a1, int a2, int a3)
{
BOOST_TEST( a0 == stored_a0 );
BOOST_TEST( a1 == stored_a1 );
BOOST_TEST( a2 == stored_a2 );
BOOST_TEST( a3 == stored_a3 );
}
};

// This is a wrapper around a UserAllocator. It just registers alloc/dealloc
Expand Down Expand Up @@ -163,6 +203,32 @@ void test()
catch(const std::logic_error &) {}
}
}

{
// Test the 'pool.construct' with 2 ctor parameters
boost::object_pool<tester> pool;
for(int i=0; i < 5; ++i)
{
tester * newItem = pool.construct(i, 2*i);
newItem->check_values(i, 2*i);
}
}

#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
{
// Test the 'pool.construct' with 4 ctor parameters
// Without variadic-templates, this functionality requires
// that the end-user has run the 'detail/pool_construct.m4'
// functionality to generate a larger set of 'construct()'
// overloads. [see docs for object_pool::construct()]
boost::object_pool<tester> pool;
for(int i=0; i < 5; ++i)
{
tester * newItem = pool.construct(i, 2*i, 3*i, 5*i);
newItem->check_values(i, 2*i, 3*i, 5*i);
}
}
#endif
}

void test_alloc()
Expand Down

0 comments on commit 7f9a0ba

Please sign in to comment.