150 lines
4.1 KiB
Plaintext
150 lines
4.1 KiB
Plaintext
[/
|
|
Copyright 2019 Glen Joseph Fernandes
|
|
(glenjofe@gmail.com)
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(http://www.boost.org/LICENSE_1_0.txt)
|
|
]
|
|
|
|
[section:alloc_construct alloc_construct, alloc_destroy]
|
|
|
|
[simplesect Authors]
|
|
|
|
* Glen Fernandes
|
|
|
|
[endsimplesect]
|
|
|
|
[section Overview]
|
|
|
|
The header <boost/core/alloc_construct.hpp> provides function templates
|
|
`alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
|
|
for allocator aware and exception safe construction and destruction of objects
|
|
and arrays.
|
|
|
|
[endsect]
|
|
|
|
[section Example]
|
|
|
|
The following example allocates storage for an array of `n` elements of `T`
|
|
using an allocator `a` and constructs `T` elements in that storage. If any
|
|
exception was thrown during construction of an element, the constructed
|
|
elements are destroyed in reverse order.
|
|
|
|
```
|
|
template<class A>
|
|
auto create(A& a, std::size_t n)
|
|
{
|
|
auto p = a.allocate(n);
|
|
try {
|
|
boost::alloc_construct_n(a, boost::to_address(p), n);
|
|
} catch (...) {
|
|
a.deallocate(p, n);
|
|
throw;
|
|
}
|
|
return p;
|
|
}
|
|
```
|
|
|
|
[endsect]
|
|
|
|
[section Reference]
|
|
|
|
```
|
|
namespace boost {
|
|
|
|
template<class A, class T>
|
|
void alloc_destroy(A& a, T* p);
|
|
|
|
template<class A, class T>
|
|
void alloc_destroy_n(A& a, T* p, std::size_t n);
|
|
|
|
template<class A, class T, class Args>
|
|
void alloc_construct(A& a, T* p, Args&&... args);
|
|
|
|
template<class A, class T>
|
|
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 */
|
|
```
|
|
|
|
[section Functions]
|
|
|
|
[variablelist
|
|
[[`template<class A, class T> void alloc_destroy(A& a, T* p);`]
|
|
[[variablelist
|
|
[[Requires][`A` is an /Allocator/]]
|
|
[[Effects][`std::allocator_traits<A>::destroy(a, p)`.]]]]]
|
|
[[`template<class A, class T> void alloc_destroy_n(A& a, T* p,
|
|
std::size_t n);`]
|
|
[[variablelist
|
|
[[Requires][`A` is an /Allocator/]]
|
|
[[Effects]
|
|
[Destroys each `i`-th element in reverse order by calling
|
|
`std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
|
|
[[`template<class A, class T, class Args> void alloc_construct(A& a, T* p,
|
|
Args&&... args);`]
|
|
[[variablelist
|
|
[[Requires][`A` is an /Allocator/]]
|
|
[[Effects]
|
|
[`std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...)`.]]]]]
|
|
[[`template<class A, class T> void alloc_construct_n(A& a, T* p,
|
|
std::size_t n);`]
|
|
[[variablelist
|
|
[[Requires][`A` is an /Allocator/]]
|
|
[[Effects]
|
|
[Constructs each `i`-th element in order by calling
|
|
`std::allocator_traits<A>::construct(a, &p[i])`.]]
|
|
[[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> void alloc_construct_n(A& a, T* p, std::size_t n,
|
|
const T* l, std::size_t m);`]
|
|
[[variablelist
|
|
[[Requires][`A` is an /Allocator/]]
|
|
[[Effects]
|
|
[Constructs each `i`-th element in order by calling
|
|
`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]
|
|
[[itemized_list
|
|
[`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]
|
|
|
|
[endsect]
|
|
|
|
[section Compatibility]
|
|
|
|
When `BOOST_NO_CXX11_ALLOCATOR` is defined, and the C++11 allocator model is
|
|
not supported, these functions invoke constructors and destructors directly
|
|
without going through the supplied allocator.
|
|
|
|
[endsect]
|
|
|
|
[section Acknowledgments]
|
|
|
|
Glen Fernandes originally implemented this functionality in Boost.Smart_Ptr and
|
|
later moved these functions to Boost.Core for use in other Boost libraries,
|
|
such as Boost.Multi_Array and Boost.Histogram.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|