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/allocate_unique.adoc[]
|
||||
|
||||
include::smart_ptr/intrusive_ptr.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:
|
||||
:idprefix: changelog_
|
||||
|
||||
## Changes in 1.72.0
|
||||
|
||||
* Added `allocate_unique`
|
||||
|
||||
## Changes in 1.71.0
|
||||
|
||||
* 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 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_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`;
|
||||
* `<<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;
|
||||
|
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 weak_from_test.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