mirror of
https://github.com/boostorg/core.git
synced 2025-05-11 13:13:55 +00:00
Move construct and destroy from Smart_Ptr to Core
This commit is contained in:
parent
f3a382c017
commit
612069c7e4
125
doc/alloc_construct.qbk
Normal file
125
doc/alloc_construct.qbk
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
[/
|
||||||
|
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]
|
||||||
|
|
||||||
|
[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(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 U>
|
||||||
|
void alloc_construct(A& a, T* p, U&&... u);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
} /* 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 element in reverse order by calling
|
||||||
|
`std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
|
||||||
|
[[`template<class A, class T, class U> void alloc_construct(A& a, T* p,
|
||||||
|
U&&... u);`]
|
||||||
|
[[variablelist
|
||||||
|
[[Requires][`A` is an _Allocator_]]
|
||||||
|
[[Effects]
|
||||||
|
[`std::allocator_traits<A>::construct(a, p, std::forward<U>(u)...)`.]]]]]
|
||||||
|
[[`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 element in order by calling
|
||||||
|
`std::allocator_traits<A>::construct(a, &p[i])`.]]
|
||||||
|
[[Remarks]
|
||||||
|
[If an exception is thrown, destroys each element in reverse order by
|
||||||
|
calling `std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
|
||||||
|
[[`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 element in order by calling
|
||||||
|
`std::allocator_traits<A>::construct(a, &p[i], l[i % m])`.]]
|
||||||
|
[[Remarks]
|
||||||
|
[If an exception is thrown, destroys each element in reverse order by
|
||||||
|
calling `std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section Acknowledgments]
|
||||||
|
|
||||||
|
Glen Fernandes originally implemented this functionality in Boost.Smart_ptr and
|
||||||
|
later moved these functions to Boost.Core for use in multiple Boost libraries.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[endsect]
|
@ -39,6 +39,7 @@ criteria for inclusion is that the utility component be:
|
|||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[include addressof.qbk]
|
[include addressof.qbk]
|
||||||
|
[include alloc_construct.qbk]
|
||||||
[include checked_delete.qbk]
|
[include checked_delete.qbk]
|
||||||
[include default_allocator.qbk]
|
[include default_allocator.qbk]
|
||||||
[include demangle.qbk]
|
[include demangle.qbk]
|
||||||
|
209
include/boost/core/alloc_construct.hpp
Normal file
209
include/boost/core/alloc_construct.hpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||||||
|
#define BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||||||
|
|
||||||
|
#include <boost/core/noinit_adaptor.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_destroy(A& a, T* p)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::destroy(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_destroy_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
std::allocator_traits<A>::destroy(a, p + --n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_destroy(A&, T* p)
|
||||||
|
{
|
||||||
|
p->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_destroy_n(A&, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
p[--n].~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
class alloc_destroyer {
|
||||||
|
public:
|
||||||
|
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
|
||||||
|
: a_(a),
|
||||||
|
p_(p),
|
||||||
|
n_(0) { }
|
||||||
|
|
||||||
|
~alloc_destroyer() {
|
||||||
|
boost::alloc_destroy_n(a_, p_, n_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t& size() BOOST_NOEXCEPT {
|
||||||
|
return n_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
alloc_destroyer(const alloc_destroyer&);
|
||||||
|
alloc_destroyer& operator=(const alloc_destroyer&);
|
||||||
|
|
||||||
|
A& a_;
|
||||||
|
T* p_;
|
||||||
|
std::size_t n_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* detail */
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A& a, T* p)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class A, class T, class U, class... V>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A& a, T* p, U&& u, V&&... v)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, std::forward<U>(u),
|
||||||
|
std::forward<V>(v)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A& a, T* p, U&& u)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, std::forward<U>(u));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A& a, T* p, const U& u)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, u);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
std::allocator_traits<A>::construct(a, p + i);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||||
|
{
|
||||||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
std::allocator_traits<A>::construct(a, p + i, l[i % m]);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A&, T* p)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct(noinit_adaptor<A>&, T* p)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class A, class T, class U, class... V>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A&, T* p, U&& u, V&&... v)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(std::forward<U>(u), std::forward<V>(v)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A& a, T* p, U&& u)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(std::forward<U>(u));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
alloc_construct(A&, T* p, const U& u)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(u);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T();
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T;
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||||
|
{
|
||||||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T(l[i % m]);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* boost */
|
||||||
|
|
||||||
|
#endif
|
@ -138,6 +138,9 @@ compile use_default_test.cpp ;
|
|||||||
|
|
||||||
run default_allocator_test.cpp ;
|
run default_allocator_test.cpp ;
|
||||||
run noinit_adaptor_test.cpp ;
|
run noinit_adaptor_test.cpp ;
|
||||||
|
run alloc_construct_test.cpp ;
|
||||||
|
run alloc_construct_throws_test.cpp ;
|
||||||
|
run alloc_construct_cxx11_test.cpp ;
|
||||||
|
|
||||||
lib lib_typeid : lib_typeid.cpp : <link>shared:<define>LIB_TYPEID_DYN_LINK=1 ;
|
lib lib_typeid : lib_typeid.cpp : <link>shared:<define>LIB_TYPEID_DYN_LINK=1 ;
|
||||||
|
|
||||||
|
79
test/alloc_construct_cxx11_test.cpp
Normal file
79
test/alloc_construct_cxx11_test.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
#include <boost/core/alloc_construct.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
explicit type(int x)
|
||||||
|
: value_(x) { }
|
||||||
|
|
||||||
|
int value() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
|
||||||
|
int value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int type::count = 0;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
creator() { }
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
creator(const creator<U>&) { }
|
||||||
|
|
||||||
|
T* allocate(std::size_t size) {
|
||||||
|
return static_cast<T*>(::operator new(sizeof(T) * size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* ptr, std::size_t) {
|
||||||
|
::operator delete(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U, class V>
|
||||||
|
void construct(U* ptr, const V& value) {
|
||||||
|
::new(static_cast<void*>(ptr)) U(value + 1);
|
||||||
|
++type::count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
void destroy(U* ptr) {
|
||||||
|
ptr->~U();
|
||||||
|
--type::count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
creator<type> a;
|
||||||
|
type* p = a.allocate(1);
|
||||||
|
boost::alloc_construct(a, p, 1);
|
||||||
|
BOOST_TEST_EQ(type::count, 1);
|
||||||
|
BOOST_TEST_EQ(p->value(), 2);
|
||||||
|
boost::alloc_destroy(a, p);
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
119
test/alloc_construct_test.cpp
Normal file
119
test/alloc_construct_test.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
#include <boost/core/alloc_construct.hpp>
|
||||||
|
#include <boost/core/default_allocator.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
explicit type(int x = 0, int y = 0)
|
||||||
|
: value_(x + y) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
type(const type& other)
|
||||||
|
: value_(other.value_) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int type::count = 0;
|
||||||
|
|
||||||
|
void test_construct()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(1);
|
||||||
|
boost::alloc_construct(a, p);
|
||||||
|
BOOST_TEST_EQ(type::count, 1);
|
||||||
|
BOOST_TEST_EQ(p->value(), 0);
|
||||||
|
boost::alloc_destroy(a, p);
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
a.deallocate(p, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_construct_value()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(1);
|
||||||
|
boost::alloc_construct(a, p, 1);
|
||||||
|
BOOST_TEST_EQ(type::count, 1);
|
||||||
|
BOOST_TEST_EQ(p->value(), 1);
|
||||||
|
boost::alloc_destroy(a, p);
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
a.deallocate(p, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||||
|
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
void test_construct_args()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(1);
|
||||||
|
boost::alloc_construct(a, p, 1, 2);
|
||||||
|
BOOST_TEST_EQ(type::count, 1);
|
||||||
|
BOOST_TEST_EQ(p->value(), 3);
|
||||||
|
boost::alloc_destroy(a, p);
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
a.deallocate(p, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void test_construct_n()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(3);
|
||||||
|
boost::alloc_construct_n(a, p, 3);
|
||||||
|
BOOST_TEST_EQ(type::count, 3);
|
||||||
|
BOOST_TEST_EQ(p[0].value(), 0);
|
||||||
|
BOOST_TEST_EQ(p[1].value(), 0);
|
||||||
|
BOOST_TEST_EQ(p[2].value(), 0);
|
||||||
|
boost::alloc_destroy_n(a, p, 3);
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
a.deallocate(p, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_construct_n_list()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(3);
|
||||||
|
type q(1);
|
||||||
|
boost::alloc_construct_n(a, p, 3, &q, 1);
|
||||||
|
BOOST_TEST_EQ(type::count, 4);
|
||||||
|
BOOST_TEST_EQ(p[0].value(), 1);
|
||||||
|
BOOST_TEST_EQ(p[1].value(), 1);
|
||||||
|
BOOST_TEST_EQ(p[2].value(), 1);
|
||||||
|
boost::alloc_destroy_n(a, p, 3);
|
||||||
|
BOOST_TEST_EQ(type::count, 1);
|
||||||
|
a.deallocate(p, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_construct();
|
||||||
|
test_construct_value();
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||||
|
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
test_construct_args();
|
||||||
|
#endif
|
||||||
|
test_construct_n();
|
||||||
|
test_construct_n_list();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
46
test/alloc_construct_throws_test.cpp
Normal file
46
test/alloc_construct_throws_test.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
#include <boost/core/alloc_construct.hpp>
|
||||||
|
#include <boost/core/default_allocator.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
type() {
|
||||||
|
if (count == 4) {
|
||||||
|
throw true;
|
||||||
|
}
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int type::count = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::default_allocator<type> a;
|
||||||
|
type* p = a.allocate(5);
|
||||||
|
try {
|
||||||
|
boost::alloc_construct_n(a, p, 5);
|
||||||
|
BOOST_ERROR("construct_n did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST_EQ(type::count, 0);
|
||||||
|
}
|
||||||
|
a.deallocate(p, 5);
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user