Add alloc_construct_n overload for input iterators

This commit is contained in:
Glen Fernandes
2019-05-11 12:37:48 -04:00
parent b0df75ad1c
commit 6b65cde816
3 changed files with 51 additions and 0 deletions

View File

@ -67,6 +67,9 @@ void alloc_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);
template<class A, class T, class I>
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<A>::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<A>::destroy(a, &p[j])`.]]]]]
[[`template<class A, class T, class I> 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<A>::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<A>::destroy(a, &p[j])`.]]]]]]
[endsect]

View File

@ -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<class A, class T, class I>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
std::allocator_traits<A>::construct(a, p + i, *b);
}
hold.size() = 0;
}
#else
template<class A, class T>
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<class A, class T, class I>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
::new(static_cast<void*>(p + i)) T(*b);
}
hold.size() = 0;
}
#endif
} /* boost */

View File

@ -105,6 +105,21 @@ void test_construct_n_list()
a.deallocate(p, 3);
}
void test_construct_n_iterator()
{
boost::default_allocator<type> 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();
}