From 7f9a0ba5741a4cd49118d5c75014f25996005927 Mon Sep 17 00:00:00 2001 From: Joe Herdman Date: Fri, 6 Sep 2019 01:34:50 -0400 Subject: [PATCH] Allow object_pool::construct() to use variadic template, if available. --- include/boost/pool/object_pool.hpp | 12 ++++++ test/test_pool_alloc.cpp | 66 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/include/boost/pool/object_pool.hpp b/include/boost/pool/object_pool.hpp index 092f0178..cbaf5699 100644 --- a/include/boost/pool/object_pool.hpp +++ b/include/boost/pool/object_pool.hpp @@ -175,6 +175,18 @@ class object_pool: protected pool //! 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 + element_type * construct(Args&&... args) + { + element_type* const ret = (malloc)(); + if (ret == 0) + return ret; + try { new (ret) element_type(std::forward(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. diff --git a/test/test_pool_alloc.cpp b/test/test_pool_alloc.cpp index b0b50eab..d504c295 100644 --- a/test/test_pool_alloc.cpp +++ b/test/test_pool_alloc.cpp @@ -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); @@ -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 @@ -163,6 +203,32 @@ void test() catch(const std::logic_error &) {} } } + + { + // Test the 'pool.construct' with 2 ctor parameters + boost::object_pool 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 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()