diff --git a/doc/alloc_construct.qbk b/doc/alloc_construct.qbk index 13bc0b1..8fa47c6 100644 --- a/doc/alloc_construct.qbk +++ b/doc/alloc_construct.qbk @@ -67,6 +67,9 @@ void alloc_construct_n(A& a, T* p, std::size_t n); template void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m); +template +void alloc_construct_n(A& a, T* p, std::size_t n, I begin); + } /* boost */ ``` @@ -109,6 +112,16 @@ const T* l, std::size_t m);`] `std::allocator_traits::construct(a, &p[i], l[i % m])`.]] [[Remarks] [If an exception is thrown destroys each already constructed `j`-th element in +reverse order by calling `std::allocator_traits::destroy(a, &p[j])`.]]]]] +[[`template void alloc_construct_n(A& a, T* p, +std::size_t n, I begin);`] +[[variablelist +[[Requires][`A` is an /Allocator/; `I` is an /InputIterator/]] +[[Effects] +[Constructs each `i`-th element in order by calling +`std::allocator_traits::construct(a, &p[i], *begin++])`.]] +[[Remarks] +[If an exception is thrown destroys each already constructed `j`-th element in reverse order by calling `std::allocator_traits::destroy(a, &p[j])`.]]]]]] [endsect] diff --git a/include/boost/core/alloc_construct.hpp b/include/boost/core/alloc_construct.hpp index 2e6f9d0..c14b05c 100644 --- a/include/boost/core/alloc_construct.hpp +++ b/include/boost/core/alloc_construct.hpp @@ -130,6 +130,17 @@ alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) } hold.size() = 0; } + +template +inline void +alloc_construct_n(A& a, T* p, std::size_t n, I b) +{ + detail::alloc_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) { + std::allocator_traits::construct(a, p + i, *b); + } + hold.size() = 0; +} #else template inline void @@ -202,6 +213,17 @@ alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) } hold.size() = 0; } + +template +inline void +alloc_construct_n(A& a, T* p, std::size_t n, I b) +{ + detail::alloc_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) { + ::new(static_cast(p + i)) T(*b); + } + hold.size() = 0; +} #endif } /* boost */ diff --git a/test/alloc_construct_test.cpp b/test/alloc_construct_test.cpp index 3e46e3c..511afc6 100644 --- a/test/alloc_construct_test.cpp +++ b/test/alloc_construct_test.cpp @@ -105,6 +105,21 @@ void test_construct_n_list() a.deallocate(p, 3); } +void test_construct_n_iterator() +{ + boost::default_allocator a; + type* p = a.allocate(3); + type l[] = { type(1), type(2), type(3) }; + boost::alloc_construct_n(a, p, 3, &l[0]); + BOOST_TEST_EQ(type::count, 6); + BOOST_TEST_EQ(p[0].value(), 1); + BOOST_TEST_EQ(p[1].value(), 2); + BOOST_TEST_EQ(p[2].value(), 3); + boost::alloc_destroy_n(a, p, 3); + BOOST_TEST_EQ(type::count, 3); + a.deallocate(p, 3); +} + int main() { test_construct(); @@ -115,5 +130,6 @@ int main() #endif test_construct_n(); test_construct_n_list(); + test_construct_n_iterator(); return boost::report_errors(); }