forked from boostorg/smart_ptr
Implement allocate_unique
This commit is contained in:
@ -37,6 +37,8 @@ include::smart_ptr/enable_shared_from.adoc[]
|
|||||||
|
|
||||||
include::smart_ptr/make_unique.adoc[]
|
include::smart_ptr/make_unique.adoc[]
|
||||||
|
|
||||||
|
include::smart_ptr/allocate_unique.adoc[]
|
||||||
|
|
||||||
include::smart_ptr/intrusive_ptr.adoc[]
|
include::smart_ptr/intrusive_ptr.adoc[]
|
||||||
|
|
||||||
include::smart_ptr/intrusive_ref_counter.adoc[]
|
include::smart_ptr/intrusive_ref_counter.adoc[]
|
||||||
|
264
doc/smart_ptr/allocate_unique.adoc
Normal file
264
doc/smart_ptr/allocate_unique.adoc
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
////
|
||||||
|
Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com)
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
|
||||||
|
See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
////
|
||||||
|
|
||||||
|
[#allocate_unique]
|
||||||
|
# allocate_unique: Creating unique_ptr
|
||||||
|
:toc:
|
||||||
|
:toc-title:
|
||||||
|
:idprefix: allocate_unique_
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
The `allocate_unique` family of function templates provide convenient and safe
|
||||||
|
ways to obtain a `std::unique_ptr` that manages a new object created using an
|
||||||
|
allocator.
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
The {cpp}14 standard introduced `std::make_unique` which used operator `new` to
|
||||||
|
create new objects. However, there is no convenient facility in the standard
|
||||||
|
library to use an allocator for the creation of the objects managed by
|
||||||
|
`std::unique_ptr`. Users writing allocator aware code have often requested an
|
||||||
|
`allocate_unique` factory function. This function is to `std::unique_ptr` what
|
||||||
|
`std::allocate_shared` is to `std::shared_ptr`.
|
||||||
|
|
||||||
|
## Synopsis
|
||||||
|
|
||||||
|
`allocate_unique` is defined in `<boost/smart_ptr/allocate_unique.hpp>`.
|
||||||
|
|
||||||
|
[subs=+quotes]
|
||||||
|
```
|
||||||
|
namespace boost {
|
||||||
|
`// T is not an array`
|
||||||
|
template<class T, class A, class... Args>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, Args&&... args);
|
||||||
|
|
||||||
|
`// T is not an array`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, type_identity_t<T>&& v);
|
||||||
|
|
||||||
|
`// T is an array of unknown bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, std::size_t n);
|
||||||
|
|
||||||
|
`// T is an array of known bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a);
|
||||||
|
|
||||||
|
`// T is an array of unknown bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, std::size_t n, const type_identity_t<T>& v);
|
||||||
|
|
||||||
|
`// T is an array of known bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, const type_identity_t<T>& v);
|
||||||
|
|
||||||
|
`// T is not an array`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique_noinit(const A& a);
|
||||||
|
|
||||||
|
`// T is an array of unknown bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique(const A& a, std::size_t n);
|
||||||
|
|
||||||
|
`// T is an array of known bounds`
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique_noinit(const A& a);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Requirements
|
||||||
|
|
||||||
|
The common requirements that apply to all `allocate_unique` and
|
||||||
|
`allocate_unique_noinit` overloads, unless specified otherwise, are described
|
||||||
|
below.
|
||||||
|
|
||||||
|
Requires:: `A` shall be an _allocator_. The copy constructor and destructor
|
||||||
|
of `A` shall not throw exceptions.
|
||||||
|
|
||||||
|
Effects:: Allocates memory for an object of type `T` or `n` objects of `U`
|
||||||
|
(if `T` is an array type of the form `U[]` and `n` is determined by
|
||||||
|
arguments, as specified by the concrete overload). The object is initialized
|
||||||
|
from arguments as specified by the concrete overload. Uses a rebound copy of
|
||||||
|
`a` (for an unspecified `value_type`) to allocate memory. If an exception is
|
||||||
|
thrown, the functions have no effect.
|
||||||
|
|
||||||
|
Returns:: A `std::unique_ptr` instance that stores and owns the address of the
|
||||||
|
newly constructed object.
|
||||||
|
|
||||||
|
Postconditions:: `r.get() != 0`, where `r` is the return value.
|
||||||
|
|
||||||
|
Throws:: An exception thrown from `A::allocate`, or from the initialization of
|
||||||
|
the object.
|
||||||
|
|
||||||
|
Remarks::
|
||||||
|
* When an object of an array type is specified to be initialized to a value of
|
||||||
|
the same type `v`, this shall be interpreted to mean that each array element
|
||||||
|
of the object is initialized to the corresponding element from `v`.
|
||||||
|
* When an object of an array type is specified to be value-initialized, this
|
||||||
|
shall be interpreted to mean that each array element of the object is
|
||||||
|
value-initialized.
|
||||||
|
* When a (sub)object of non-array type `U` is specified to be initialized to a
|
||||||
|
value `v`, or constructed from `args\...`, `allocate_unique` shall perform this
|
||||||
|
initialization via the expression
|
||||||
|
`std::allocator_traits<A2>::construct(a2, p, expr)` (where `_expr_` is `v` or
|
||||||
|
`std::forward<Args>(args)\...)` respectively), `p` points to storage suitable
|
||||||
|
to hold an object of type `U`, and `a2` of type `A2` is a rebound copy `a` such
|
||||||
|
that its `value_type` is `U`.
|
||||||
|
* When a (sub)object of non-array type `U` is specified to be
|
||||||
|
default-initialized, `allocate_unique_noinit` shall perform this initialization
|
||||||
|
via the expression `::new(p) U`, where `p` has type `void*` and points to
|
||||||
|
storage suitable to hold an object of type `U`.
|
||||||
|
* When a (sub)object of non-array type `U` is specified to be
|
||||||
|
value-initialized, `allocate_unique` shall perform this initialization via the
|
||||||
|
expression `std::allocator_traits<A2>::construct(a2, p)`, where `p` points to
|
||||||
|
storage suitable to hold an object of type `U` and `a2` of type `A2` is a
|
||||||
|
rebound copy of `a` such that its value_type is `U`.
|
||||||
|
* Array elements are initialized in ascending order of their addresses.
|
||||||
|
* When the lifetime of the object managed by the return value ends, or when the
|
||||||
|
initialization of an array element throws an exception, the initialized
|
||||||
|
elements should be destroyed in the reverse order of their construction.
|
||||||
|
|
||||||
|
## Free Functions
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A, class... Args>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, Args&&... args);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is not an array.
|
||||||
|
Returns:: A `std::unique_ptr` to an object of type `T`, constructed from
|
||||||
|
`args\...`.
|
||||||
|
Examples::
|
||||||
|
* `auto p = allocate_unique<int>(a);`
|
||||||
|
* `auto p = allocate_unique<std::vector<int>>(a, 16, 1);`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, type_identity_t<T>&& v);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is not an array.
|
||||||
|
Returns:: A `std::unique_ptr` to an object of type `T`, constructed from `v`.
|
||||||
|
Example:: `auto p = allocate_unique<std::vector<int>>(a, {1, 2});`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, std::size_t n);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of unknown bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `n` value-initialized objects of
|
||||||
|
type `remove_extent_t<T>`.
|
||||||
|
Examples::
|
||||||
|
* `auto p = allocate_unique<double[]>(a, 1024);`
|
||||||
|
* `auto p = allocate_unique<double[][2][2]>(a, 6);`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of known bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` value-initialized
|
||||||
|
objects of type `remove_extent_t<T>`.
|
||||||
|
Examples::
|
||||||
|
* `auto p = allocate_unique<double[1024]>(a);`
|
||||||
|
* `auto p = allocate_unique<double[6][2][2]>(a);`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, std::size_t n, const type_identity_t<T>& v);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of unknown bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `n` objects of type
|
||||||
|
`remove_extent_t<T>`, each initialized to `v`.
|
||||||
|
Examples::
|
||||||
|
* `auto p = allocate_unique<double[]>(a, 1024, 1.0);`
|
||||||
|
* `auto p = allocate_unique<double[][2]>(a, 6, {1.0, 0.0});`
|
||||||
|
* `auto p = allocate_unique<std::vector<int>[]>(a, 4, {1, 2});`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
|
||||||
|
allocate_unique(const A& a, const type_identity_t<T>& v);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of known bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` objects of type
|
||||||
|
`remove_extent_t<T>`, each initialized to `v`.
|
||||||
|
Examples::
|
||||||
|
* `auto p = allocate_unique<double[1024]>(a, 1.0);`
|
||||||
|
* `auto p = allocate_unique<double[6][2]>(a, {1.0, 0.0});`
|
||||||
|
* `auto p = allocate_unique<std::vector<int>[4]>(a, {1, 2});`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique_noinit(const A& a);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is not an array.
|
||||||
|
Returns:: A `std::unique_ptr` to a default-initialized object of type `T`.
|
||||||
|
Example:: `auto p = allocate_unique_noinit<double>(a);`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique(const A& a, std::size_t n);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of unknown bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `n` default-initialized objects
|
||||||
|
of type `remove_extent_t<T>`.
|
||||||
|
Example:: `auto p = allocate_unique_noinit<double[]>(a, 1024);`
|
||||||
|
|
||||||
|
```
|
||||||
|
template<class T, class A>
|
||||||
|
std::unique_ptr<remove_extent_t<T>, alloc_deleter<T, noinit_adaptor<A>>>
|
||||||
|
allocate_unique_noinit(const A& a);
|
||||||
|
```
|
||||||
|
[none]
|
||||||
|
* {blank}
|
||||||
|
+
|
||||||
|
Constraints:: `T` is an array of known bounds.
|
||||||
|
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>`
|
||||||
|
default-initialized objects of type `remove_extent_t<T>`.
|
||||||
|
Example:: `auto p = allocate_unique_noinit<double[1024]>(a);`
|
@ -13,6 +13,10 @@ http://www.boost.org/LICENSE_1_0.txt
|
|||||||
:toc-title:
|
:toc-title:
|
||||||
:idprefix: changelog_
|
:idprefix: changelog_
|
||||||
|
|
||||||
|
## Changes in 1.72.0
|
||||||
|
|
||||||
|
* Added `allocate_unique`
|
||||||
|
|
||||||
## Changes in 1.71.0
|
## Changes in 1.71.0
|
||||||
|
|
||||||
* Added aliasing constructors to `weak_ptr`
|
* Added aliasing constructors to `weak_ptr`
|
||||||
|
@ -111,3 +111,7 @@ Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more
|
|||||||
Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.
|
Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.
|
||||||
|
|
||||||
Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`.
|
Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`.
|
||||||
|
|
||||||
|
## August 2019
|
||||||
|
|
||||||
|
Glen Fernandes implemented `allocate_unique` for scalars and arrays.
|
||||||
|
@ -41,6 +41,7 @@ In addition, the library contains the following supporting utility functions and
|
|||||||
|
|
||||||
* `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`;
|
* `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`;
|
||||||
* `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`;
|
* `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`;
|
||||||
|
* `<<allocate_unique,allocate_unique>>`, a factory function for creating objects using an allocator that returns a `std::unique_ptr`;
|
||||||
* `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
|
* `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
|
||||||
* `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another;
|
* `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another;
|
||||||
* `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts;
|
* `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts;
|
||||||
|
501
include/boost/smart_ptr/allocate_unique.hpp
Normal file
501
include/boost/smart_ptr/allocate_unique.hpp
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
/*
|
||||||
|
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_SMART_PTR_ALLOCATE_UNIQUE_HPP
|
||||||
|
#define BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
|
#include <boost/core/alloc_construct.hpp>
|
||||||
|
#include <boost/core/empty_value.hpp>
|
||||||
|
#include <boost/core/first_scalar.hpp>
|
||||||
|
#include <boost/core/noinit_adaptor.hpp>
|
||||||
|
#include <boost/core/pointer_traits.hpp>
|
||||||
|
#include <boost/type_traits/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/extent.hpp>
|
||||||
|
#include <boost/type_traits/is_array.hpp>
|
||||||
|
#include <boost/type_traits/is_bounded_array.hpp>
|
||||||
|
#include <boost/type_traits/is_unbounded_array.hpp>
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
#include <boost/type_traits/remove_extent.hpp>
|
||||||
|
#include <boost/type_traits/type_identity.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct sp_alloc_size {
|
||||||
|
BOOST_STATIC_CONSTEXPR std::size_t value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct sp_alloc_size<T[]> {
|
||||||
|
BOOST_STATIC_CONSTEXPR std::size_t value = sp_alloc_size<T>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, std::size_t N>
|
||||||
|
struct sp_alloc_size<T[N]> {
|
||||||
|
BOOST_STATIC_CONSTEXPR std::size_t value = N * sp_alloc_size<T>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct sp_alloc_result {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, std::size_t N>
|
||||||
|
struct sp_alloc_result<T[N]> {
|
||||||
|
typedef T type[];
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct sp_alloc_value {
|
||||||
|
typedef typename boost::remove_cv<typename
|
||||||
|
boost::remove_extent<T>::type>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
template<class A, class T>
|
||||||
|
struct sp_alloc_to {
|
||||||
|
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<class A, class T>
|
||||||
|
struct sp_alloc_to {
|
||||||
|
typedef typename A::template rebind<T>::other type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
template<class A>
|
||||||
|
struct sp_alloc_type {
|
||||||
|
typedef typename std::allocator_traits<A>::pointer type;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<class A>
|
||||||
|
struct sp_alloc_type {
|
||||||
|
typedef typename A::pointer type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
class sp_alloc_ptr {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
sp_alloc_ptr() BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
|
||||||
|
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
|
||||||
|
: p_(p) { }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
T& operator*() const {
|
||||||
|
return *p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const BOOST_SP_NOEXCEPT {
|
||||||
|
return boost::to_address(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||||
|
explicit operator bool() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !!p_;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool operator!() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
P ptr() const BOOST_SP_NOEXCEPT {
|
||||||
|
return p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
|
||||||
|
static sp_alloc_ptr pointer_to(T& v) {
|
||||||
|
return sp_alloc_ptr(1,
|
||||||
|
std::pointer_traits<P>::pointer_to(const_cast<typename
|
||||||
|
boost::remove_cv<T>::type&>(v)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
P p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
class sp_alloc_ptr<T[], P> {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
sp_alloc_ptr() BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
|
||||||
|
sp_alloc_ptr(std::size_t n, P p) BOOST_SP_NOEXCEPT
|
||||||
|
: p_(p)
|
||||||
|
, n_(n) { }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
T& operator[](std::size_t i) const {
|
||||||
|
return p_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||||
|
explicit operator bool() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !!p_;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool operator!() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
P ptr() const BOOST_SP_NOEXCEPT {
|
||||||
|
return p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const BOOST_SP_NOEXCEPT {
|
||||||
|
return n_;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
|
||||||
|
static sp_alloc_ptr pointer_to(T& v) {
|
||||||
|
return sp_alloc_ptr(n_,
|
||||||
|
std::pointer_traits<P>::pointer_to(const_cast<typename
|
||||||
|
boost::remove_cv<T>::type&>(v)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
P p_;
|
||||||
|
std::size_t n_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, std::size_t N, class P>
|
||||||
|
class sp_alloc_ptr<T[N], P> {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
sp_alloc_ptr() BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
|
||||||
|
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
|
||||||
|
: p_(p) { }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
|
||||||
|
: p_() { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
T& operator[](std::size_t i) const {
|
||||||
|
return p_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||||
|
explicit operator bool() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !!p_;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool operator!() const BOOST_SP_NOEXCEPT {
|
||||||
|
return !p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
P ptr() const BOOST_SP_NOEXCEPT {
|
||||||
|
return p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_NOEXCEPT {
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
|
||||||
|
static sp_alloc_ptr pointer_to(T& v) {
|
||||||
|
return sp_alloc_ptr(N,
|
||||||
|
std::pointer_traits<P>::pointer_to(const_cast<typename
|
||||||
|
boost::remove_cv<T>::type&>(v)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
P p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator==(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
|
||||||
|
{
|
||||||
|
return lhs.ptr() == rhs.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator!=(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator==(const sp_alloc_ptr<T, P>& lhs,
|
||||||
|
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !lhs.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator==(detail::sp_nullptr_t,
|
||||||
|
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !rhs.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator!=(const sp_alloc_ptr<T, P>& lhs,
|
||||||
|
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !!lhs.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class P>
|
||||||
|
inline bool
|
||||||
|
operator!=(detail::sp_nullptr_t,
|
||||||
|
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !!rhs.ptr();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A>
|
||||||
|
inline void
|
||||||
|
sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t,
|
||||||
|
boost::false_type)
|
||||||
|
{
|
||||||
|
boost::alloc_destroy(a, p);
|
||||||
|
a.deallocate(p, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A>
|
||||||
|
inline void
|
||||||
|
sp_alloc_clear(A& a, typename sp_alloc_type<A>::type p, std::size_t n,
|
||||||
|
boost::true_type)
|
||||||
|
{
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1800
|
||||||
|
if (!p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
boost::alloc_destroy_n(a, boost::first_scalar(boost::to_address(p)),
|
||||||
|
n * sp_alloc_size<typename A::value_type>::value);
|
||||||
|
a.deallocate(p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* detail */
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
class alloc_deleter
|
||||||
|
: empty_value<typename detail::sp_alloc_to<A,
|
||||||
|
typename detail::sp_alloc_value<T>::type>::type> {
|
||||||
|
typedef typename detail::sp_alloc_to<A,
|
||||||
|
typename detail::sp_alloc_value<T>::type>::type allocator;
|
||||||
|
typedef empty_value<allocator> base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef detail::sp_alloc_ptr<T,
|
||||||
|
typename detail::sp_alloc_type<allocator>::type> pointer;
|
||||||
|
|
||||||
|
explicit alloc_deleter(const allocator& a) BOOST_SP_NOEXCEPT
|
||||||
|
: base(empty_init_t(), a) { }
|
||||||
|
|
||||||
|
void operator()(pointer p) {
|
||||||
|
detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), is_array<T>());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||||
|
template<class T, class A>
|
||||||
|
using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
class sp_alloc_make {
|
||||||
|
public:
|
||||||
|
typedef typename sp_alloc_to<A,
|
||||||
|
typename sp_alloc_value<T>::type>::type allocator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef boost::alloc_deleter<T, A> deleter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::unique_ptr<typename sp_alloc_result<T>::type, deleter> type;
|
||||||
|
|
||||||
|
sp_alloc_make(const A& a, std::size_t n)
|
||||||
|
: a_(a)
|
||||||
|
, n_(n)
|
||||||
|
, p_(a_.allocate(n)) { }
|
||||||
|
|
||||||
|
~sp_alloc_make() {
|
||||||
|
if (p_) {
|
||||||
|
a_.deallocate(p_, n_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typename allocator::value_type* get() const BOOST_SP_NOEXCEPT {
|
||||||
|
return boost::to_address(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator& state() BOOST_SP_NOEXCEPT {
|
||||||
|
return a_;
|
||||||
|
}
|
||||||
|
|
||||||
|
type release() BOOST_SP_NOEXCEPT {
|
||||||
|
pointer p = p_;
|
||||||
|
p_ = pointer();
|
||||||
|
return type(typename deleter::pointer(n_, p), deleter(a_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef typename sp_alloc_type<allocator>::type pointer;
|
||||||
|
|
||||||
|
allocator a_;
|
||||||
|
std::size_t n_;
|
||||||
|
pointer p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* detail */
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<!is_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, 1);
|
||||||
|
boost::alloc_construct(c.state(), c.get());
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class T, class A, class... Args>
|
||||||
|
inline typename enable_if_<!is_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc, Args&&... args)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, 1);
|
||||||
|
boost::alloc_construct(c.state(), c.get(), std::forward<Args>(args)...);
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<!is_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc, typename type_identity<T>::type&& value)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, 1);
|
||||||
|
boost::alloc_construct(c.state(), c.get(), std::move(value));
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<!is_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
|
||||||
|
allocate_unique_noinit(const A& alloc)
|
||||||
|
{
|
||||||
|
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc, std::size_t size)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, size);
|
||||||
|
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
|
||||||
|
size * detail::sp_alloc_size<T>::value);
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
|
||||||
|
alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, extent<T>::value);
|
||||||
|
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
|
||||||
|
detail::sp_alloc_size<T>::value);
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
|
||||||
|
allocate_unique_noinit(const A& alloc, std::size_t size)
|
||||||
|
{
|
||||||
|
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
|
||||||
|
alloc_deleter<T, noinit_adaptor<A> > > >::type
|
||||||
|
allocate_unique_noinit(const A& alloc)
|
||||||
|
{
|
||||||
|
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
std::unique_ptr<T, alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc, std::size_t size,
|
||||||
|
const typename remove_extent<T>::type& value)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, size);
|
||||||
|
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
|
||||||
|
size * detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
|
||||||
|
detail::sp_alloc_size<typename remove_extent<T>::type>::value);
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class A>
|
||||||
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
|
||||||
|
alloc_deleter<T, A> > >::type
|
||||||
|
allocate_unique(const A& alloc,
|
||||||
|
const typename remove_extent<T>::type& value)
|
||||||
|
{
|
||||||
|
detail::sp_alloc_make<T, A> c(alloc, extent<T>::value);
|
||||||
|
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
|
||||||
|
detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
|
||||||
|
detail::sp_alloc_size<typename remove_extent<T>::type>::value);
|
||||||
|
return c.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* boost */
|
||||||
|
|
||||||
|
#endif
|
12
test/Jamfile
12
test/Jamfile
@ -319,3 +319,15 @@ run get_deleter_test3.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>n
|
|||||||
run shared_from_test.cpp ;
|
run shared_from_test.cpp ;
|
||||||
run weak_from_test.cpp ;
|
run weak_from_test.cpp ;
|
||||||
run weak_from_test2.cpp ;
|
run weak_from_test2.cpp ;
|
||||||
|
|
||||||
|
run allocate_unique_args_test.cpp ;
|
||||||
|
run allocate_unique_array_construct_test.cpp ;
|
||||||
|
run allocate_unique_array_noinit_test.cpp ;
|
||||||
|
run allocate_unique_arrays_test.cpp ;
|
||||||
|
run allocate_unique_array_test.cpp ;
|
||||||
|
run allocate_unique_array_throws_test.cpp ;
|
||||||
|
run allocate_unique_array_value_test.cpp ;
|
||||||
|
run allocate_unique_construct_test.cpp ;
|
||||||
|
run allocate_unique_noinit_test.cpp ;
|
||||||
|
run allocate_unique_test.cpp ;
|
||||||
|
run allocate_unique_throws_test.cpp ;
|
||||||
|
111
test/allocate_unique_args_test.cpp
Normal file
111
test/allocate_unique_args_test.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 46000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR) && \
|
||||||
|
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type(int v1, int v2, int v3, int v4, int v5)
|
||||||
|
: sum_(v1 + v2 + v3 + v4 + v5) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum() const {
|
||||||
|
return sum_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int sum_;
|
||||||
|
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
std::unique_ptr<type,
|
||||||
|
boost::alloc_deleter<type, creator<type> > > result =
|
||||||
|
boost::allocate_unique<type>(creator<type>(), 1, 2, 3, 4, 5);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
BOOST_TEST(result->sum() == 15);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type,
|
||||||
|
boost::alloc_deleter<const type, creator<> > > result =
|
||||||
|
boost::allocate_unique<const type>(creator<>(), 1, 2, 3, 4, 5);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
BOOST_TEST(result->sum() == 15);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
166
test/allocate_unique_array_construct_test.cpp
Normal file
166
test/allocate_unique_array_construct_test.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR) && \
|
||||||
|
!defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
struct allow { };
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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>
|
||||||
|
void construct(U* ptr) {
|
||||||
|
::new(static_cast<void*>(ptr)) U(allow());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
void destroy(U* ptr) {
|
||||||
|
ptr->~U();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
explicit type(allow) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[], creator<type> > > result =
|
||||||
|
boost::allocate_unique<type[]>(creator<type>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[3], creator<type> > > result =
|
||||||
|
boost::allocate_unique<type[3]>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[]>(creator<>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[3], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[3]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
228
test/allocate_unique_array_noinit_test.cpp
Normal file
228
test/allocate_unique_array_noinit_test.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type()
|
||||||
|
: value_(0.0) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(long double value) {
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double get() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
|
||||||
|
long double value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[],
|
||||||
|
boost::noinit_adaptor<creator<int> > > > result =
|
||||||
|
boost::allocate_unique_noinit<int[]>(creator<int>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[3],
|
||||||
|
boost::noinit_adaptor<creator<int> > > > result =
|
||||||
|
boost::allocate_unique_noinit<int[3]>(creator<int>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<int[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[2][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<int[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const int[]>(creator<>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[3],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const int[3]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const int[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[2][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const int[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[],
|
||||||
|
boost::noinit_adaptor<creator<type> > > > result =
|
||||||
|
boost::allocate_unique_noinit<type[]>(creator<type>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[3],
|
||||||
|
boost::noinit_adaptor<creator<type> > > > result =
|
||||||
|
boost::allocate_unique_noinit<type[3]>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[2][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const type[]>(creator<>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[3],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const type[3]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[2][2],
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
240
test/allocate_unique_array_test.cpp
Normal file
240
test/allocate_unique_array_test.cpp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type()
|
||||||
|
: value_(0.0) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(long double value) {
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double get() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
|
||||||
|
long double value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[]>(creator<int>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0] == 0);
|
||||||
|
BOOST_TEST(result[1] == 0);
|
||||||
|
BOOST_TEST(result[2] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[3], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[3]>(creator<int>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0] == 0);
|
||||||
|
BOOST_TEST(result[1] == 0);
|
||||||
|
BOOST_TEST(result[2] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<int[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 0);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<int[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 0);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[]>(creator<>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0] == 0);
|
||||||
|
BOOST_TEST(result[1] == 0);
|
||||||
|
BOOST_TEST(result[2] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[3], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[3]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0] == 0);
|
||||||
|
BOOST_TEST(result[1] == 0);
|
||||||
|
BOOST_TEST(result[2] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 0);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 0);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[], creator<type> > > result =
|
||||||
|
boost::allocate_unique<type[]>(creator<type>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[],
|
||||||
|
boost::alloc_deleter<type[3], creator<type> > > result =
|
||||||
|
boost::allocate_unique<type[3]>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type[][2],
|
||||||
|
boost::alloc_deleter<type[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[]>(creator<>(), 3);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[],
|
||||||
|
boost::alloc_deleter<const type[3], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[3]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[][2]>(creator<>(), 2);
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type[][2],
|
||||||
|
boost::alloc_deleter<const type[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const type[2][2]>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
132
test/allocate_unique_array_throws_test.cpp
Normal file
132
test/allocate_unique_array_throws_test.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type() {
|
||||||
|
if (instances == 5) {
|
||||||
|
throw true;
|
||||||
|
}
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<type[]>(creator<type>(), 6);
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<type[][2]>(creator<type>(), 3);
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<type[6]>(creator<>());
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<type[3][2]>(creator<>());
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique_noinit<type[]>(creator<>(), 6);
|
||||||
|
BOOST_ERROR("allocate_unique_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique_noinit<type[][2]>(creator<>(), 3);
|
||||||
|
BOOST_ERROR("allocate_unique_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique_noinit<type[6]>(creator<>());
|
||||||
|
BOOST_ERROR("allocate_unique_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique_noinit<type[3][2]>(creator<>());
|
||||||
|
BOOST_ERROR("allocate_unique_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
98
test/allocate_unique_array_value_test.cpp
Normal file
98
test/allocate_unique_array_value_test.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[]>(creator<int>(), 4, 1);
|
||||||
|
BOOST_TEST(result[0] == 1);
|
||||||
|
BOOST_TEST(result[1] == 1);
|
||||||
|
BOOST_TEST(result[2] == 1);
|
||||||
|
BOOST_TEST(result[3] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[],
|
||||||
|
boost::alloc_deleter<int[4], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[4]>(creator<int>(), 1);
|
||||||
|
BOOST_TEST(result[0] == 1);
|
||||||
|
BOOST_TEST(result[1] == 1);
|
||||||
|
BOOST_TEST(result[2] == 1);
|
||||||
|
BOOST_TEST(result[3] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[]>(creator<>(), 4, 1);
|
||||||
|
BOOST_TEST(result[0] == 1);
|
||||||
|
BOOST_TEST(result[1] == 1);
|
||||||
|
BOOST_TEST(result[2] == 1);
|
||||||
|
BOOST_TEST(result[3] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[],
|
||||||
|
boost::alloc_deleter<const int[4], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[4]>(creator<>(), 1);
|
||||||
|
BOOST_TEST(result[0] == 1);
|
||||||
|
BOOST_TEST(result[1] == 1);
|
||||||
|
BOOST_TEST(result[2] == 1);
|
||||||
|
BOOST_TEST(result[3] == 1);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
99
test/allocate_unique_arrays_test.cpp
Normal file
99
test/allocate_unique_arrays_test.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 48000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR) && \
|
||||||
|
!defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[][2], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[][2]>(creator<int>(), 2, {0, 1});
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 1);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<int[][2],
|
||||||
|
boost::alloc_deleter<int[2][2], creator<int> > > result =
|
||||||
|
boost::allocate_unique<int[2][2]>(creator<int>(), {0, 1});
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 1);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[][2]>(creator<>(), 2, {0, 1});
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 1);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int[][2],
|
||||||
|
boost::alloc_deleter<const int[2][2], creator<> > > result =
|
||||||
|
boost::allocate_unique<const int[2][2]>(creator<>(), {0, 1});
|
||||||
|
BOOST_TEST(result[0][0] == 0);
|
||||||
|
BOOST_TEST(result[0][1] == 1);
|
||||||
|
BOOST_TEST(result[1][0] == 0);
|
||||||
|
BOOST_TEST(result[1][1] == 1);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
109
test/allocate_unique_construct_test.cpp
Normal file
109
test/allocate_unique_construct_test.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
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_SMART_PTR) && !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
struct allow { };
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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>
|
||||||
|
void construct(U* ptr) {
|
||||||
|
::new(static_cast<void*>(ptr)) U(allow());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
void destroy(U* ptr) {
|
||||||
|
ptr->~U();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
explicit type(allow) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<type,
|
||||||
|
boost::alloc_deleter<type, creator<type> > > result =
|
||||||
|
boost::allocate_unique<type>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type,
|
||||||
|
boost::alloc_deleter<const type, creator<> > > result =
|
||||||
|
boost::allocate_unique<const type>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
126
test/allocate_unique_noinit_test.cpp
Normal file
126
test/allocate_unique_noinit_test.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 46000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type()
|
||||||
|
: value_(0.0) {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(long double value) {
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double get() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
|
||||||
|
long double value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int,
|
||||||
|
boost::alloc_deleter<int,
|
||||||
|
boost::noinit_adaptor<creator<int> > > > result =
|
||||||
|
boost::allocate_unique_noinit<int>(creator<int>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int,
|
||||||
|
boost::alloc_deleter<const int,
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const int>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<type,
|
||||||
|
boost::alloc_deleter<type,
|
||||||
|
boost::noinit_adaptor<creator<type> > > > result =
|
||||||
|
boost::allocate_unique_noinit<type>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type,
|
||||||
|
boost::alloc_deleter<const type,
|
||||||
|
boost::noinit_adaptor<creator<> > > > result =
|
||||||
|
boost::allocate_unique_noinit<const type>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
115
test/allocate_unique_test.cpp
Normal file
115
test/allocate_unique_test.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 46000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type() {
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_ptr<int,
|
||||||
|
boost::alloc_deleter<int, creator<int> > > result =
|
||||||
|
boost::allocate_unique<int>(creator<int>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(*result == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::unique_ptr<const int,
|
||||||
|
boost::alloc_deleter<const int, creator<> > > result =
|
||||||
|
boost::allocate_unique<const int>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(*result == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
std::unique_ptr<type,
|
||||||
|
boost::alloc_deleter<type, creator<type> > > result =
|
||||||
|
boost::allocate_unique<type>(creator<type>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
std::unique_ptr<const type,
|
||||||
|
boost::alloc_deleter<const type, creator<> > > result =
|
||||||
|
boost::allocate_unique<const type>(creator<>());
|
||||||
|
BOOST_TEST(result.get() != 0);
|
||||||
|
BOOST_TEST(type::instances == 1);
|
||||||
|
result.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
96
test/allocate_unique_throws_test.cpp
Normal file
96
test/allocate_unique_throws_test.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
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_LIBSTDCXX_VERSION) || \
|
||||||
|
BOOST_LIBSTDCXX_VERSION >= 46000) && \
|
||||||
|
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_unique.hpp>
|
||||||
|
|
||||||
|
template<class T = void>
|
||||||
|
struct creator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef creator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 T, class U>
|
||||||
|
inline bool
|
||||||
|
operator==(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline bool
|
||||||
|
operator!=(const creator<T>&, const creator<U>&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned instances;
|
||||||
|
|
||||||
|
type() {
|
||||||
|
if (instances == 0) {
|
||||||
|
throw true;
|
||||||
|
}
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~type() {
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned type::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<type>(creator<type>());
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
boost::allocate_unique<const type>(creator<>());
|
||||||
|
BOOST_ERROR("allocate_unique did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
Reference in New Issue
Block a user