[/
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]
