Add allocator_construct_n to allocator_access and deprecate alloc_construct

This commit is contained in:
Glen Fernandes committed 2022-03-12 10:45:05 -05:00
1 parent c4deb479fd
commit 4defdfd233
8 files changed
+214 -232

No files matched your search

+59 -1
View File
@@ -1,5 +1,5 @@
[/
Copyright 2020 Glen Joseph Fernandes
Copyright 2020-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -21,6 +21,9 @@ templates to simplify allocator use. It provides the same functionality as the
C++ standard library `std::allocator_traits` but with individual templates for
each allocator feature.
It also adds additional functionality for allocator aware exception safe
construction and destruction of arrays.
These facilities also simplify existing libraries by avoiding having to check
for `BOOST_NO_CXX11_ALLOCATOR` and conditionally use `std::allocator_traits`.
@@ -51,6 +54,26 @@ public:
In C++11 or above, aliases such as `boost::allocator_pointer_t<A>` can be used
instead of `typename boost::allocator_pointer<A>::type`.
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::allocator_construct_n(a, boost::to_address(p), n);
} catch (...) {
a.deallocate(p, n);
throw;
}
return p;
}
```
[endsect]
[section Reference]
@@ -150,9 +173,22 @@ void allocator_deallocate(A& a, allocator_pointer_t<A> p,
template<class A, class T, class... Args>
void allocator_construct(A& a, T* p, Args&&... args);
template<class A, class T>
void allocator_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void allocator_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 allocator_construct_n(A& a, T* p, std::size_t n, I begin);
template<class A, class T>
void allocator_destroy(A& a, T* p);
template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);
template<class A>
allocator_size_type_t<A> allocator_max_size(const A& a);
@@ -220,8 +256,30 @@ allocator_size_type_t<A> n);`]
void allocator_construct(A& a, T*p, Args&&... args);`]
[Calls `a.construct(p, std::forward<Args>(args)...)` if valid, otherwise calls
`::new(static_cast<void*>(p)) T(std::forward<Args>(args)...)`.]]
[[`template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_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);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], l[i % m])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_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);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], *begin++)`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T> void allocator_destroy(A& a, T* p);`]
[Calls `a.destroy(p)` if valid, otherwise calls `p->~T()`.]]
[[`template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);`]
[Destroys each `i`-th element in reverse order by calling
`boost::allocator_destroy(a, &p[i])`.]]
[[`template<class A> allocator_size_type_t<A> allocator_max_size(const A& a);`]
[Returns `a.max_size()` if valid, otherwise returns
`std::numeric_limits<allocator_size_type_t<A> >::max() /