forked from boostorg/smart_ptr
Use traits from TypeTraits
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017 Glen Joseph Fernandes
|
Copyright 2017-2019 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@ -14,22 +14,6 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct lsp_if_array { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct lsp_if_array<T[]> {
|
|
||||||
typedef boost::local_shared_ptr<T[]> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct lsp_if_size_array { };
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct lsp_if_size_array<T[N]> {
|
|
||||||
typedef boost::local_shared_ptr<T[N]> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BOOST_SYMBOL_VISIBLE lsp_array_base
|
class BOOST_SYMBOL_VISIBLE lsp_array_base
|
||||||
: public local_counted_base {
|
: public local_counted_base {
|
||||||
public:
|
public:
|
||||||
@ -84,15 +68,16 @@ private:
|
|||||||
} /* detail */
|
} /* detail */
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared(const A& allocator, std::size_t count)
|
allocate_local_shared(const A& allocator, std::size_t count)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::lsp_array_state<other> state;
|
typedef detail::lsp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
base* node = result.get();
|
base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
@ -105,15 +90,16 @@ allocate_local_shared(const A& allocator, std::size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared(const A& allocator)
|
allocate_local_shared(const A& allocator)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::lsp_size_array_state<other, size> state;
|
typedef detail::lsp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
@ -128,22 +114,25 @@ allocate_local_shared(const A& allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared(const A& allocator, std::size_t count,
|
allocate_local_shared(const A& allocator, std::size_t count,
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::lsp_array_state<other> state;
|
typedef detail::lsp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
enum {
|
||||||
|
total = detail::sp_array_count<type, scalar>::value
|
||||||
|
};
|
||||||
|
std::size_t size = count * total;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
base* node = result.get();
|
base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
::new(static_cast<void*>(node)) base(allocator, size,
|
::new(static_cast<void*>(node)) base(allocator, size,
|
||||||
reinterpret_cast<const scalar*>(&value),
|
reinterpret_cast<const scalar*>(&value), total, start);
|
||||||
detail::sp_array_count<type>::value, start);
|
|
||||||
detail::lsp_array_base& local = node->state().base();
|
detail::lsp_array_base& local = node->state().base();
|
||||||
local.set(node);
|
local.set(node);
|
||||||
result.release();
|
result.release();
|
||||||
@ -152,16 +141,17 @@ allocate_local_shared(const A& allocator, std::size_t count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared(const A& allocator,
|
allocate_local_shared(const A& allocator,
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::lsp_size_array_state<other, size> state;
|
typedef detail::lsp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
@ -169,7 +159,7 @@ allocate_local_shared(const A& allocator,
|
|||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
::new(static_cast<void*>(node)) base(allocator, size,
|
::new(static_cast<void*>(node)) base(allocator, size,
|
||||||
reinterpret_cast<const scalar*>(&value),
|
reinterpret_cast<const scalar*>(&value),
|
||||||
detail::sp_array_count<type>::value, start);
|
detail::sp_array_count<type, scalar>::value, start);
|
||||||
detail::lsp_array_base& local = node->state().base();
|
detail::lsp_array_base& local = node->state().base();
|
||||||
local.set(node);
|
local.set(node);
|
||||||
result.release();
|
result.release();
|
||||||
@ -178,15 +168,16 @@ allocate_local_shared(const A& allocator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared_noinit(const A& allocator, std::size_t count)
|
allocate_local_shared_noinit(const A& allocator, std::size_t count)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::lsp_array_state<other> state;
|
typedef detail::lsp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state, false> base;
|
typedef detail::sp_array_base<state, false> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
base* node = result.get();
|
base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
@ -200,15 +191,16 @@ allocate_local_shared_noinit(const A& allocator, std::size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
allocate_local_shared_noinit(const A& allocator)
|
allocate_local_shared_noinit(const A& allocator)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::lsp_size_array_state<other, size> state;
|
typedef detail::lsp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state, false> base;
|
typedef detail::sp_array_base<state, false> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012-2018 Glen Joseph Fernandes
|
Copyright 2012-2019 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@ -10,99 +10,30 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
|
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
#include <boost/type_traits/alignment_of.hpp>
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
#include <boost/type_traits/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/is_bounded_array.hpp>
|
||||||
|
#include <boost/type_traits/is_unbounded_array.hpp>
|
||||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||||
|
#include <boost/type_traits/remove_all_extents.hpp>
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
#include <boost/type_traits/remove_extent.hpp>
|
||||||
#include <boost/type_traits/type_with_alignment.hpp>
|
#include <boost/type_traits/type_with_alignment.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct sp_if_array { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_if_array<T[]> {
|
|
||||||
typedef boost::shared_ptr<T[]> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct sp_if_size_array { };
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_if_size_array<T[N]> {
|
|
||||||
typedef boost::shared_ptr<T[N]> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct sp_array_element { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_element<T[]> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_array_element<T[N]> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct sp_array_scalar {
|
struct sp_array_scalar {
|
||||||
typedef T type;
|
typedef typename boost::remove_cv<typename
|
||||||
|
boost::remove_all_extents<T>::type>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
template<class T, class U>
|
||||||
struct sp_array_scalar<T[N]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_array_scalar<const T[N]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_array_scalar<volatile T[N]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_array_scalar<const volatile T[N]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_scalar<T[]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_scalar<const T[]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_scalar<volatile T[]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_scalar<const volatile T[]> {
|
|
||||||
typedef typename sp_array_scalar<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_array_count {
|
struct sp_array_count {
|
||||||
enum {
|
enum {
|
||||||
value = 1
|
value = sizeof(T) / sizeof(U)
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct sp_array_count<T[N]> {
|
|
||||||
enum {
|
|
||||||
value = N * sp_array_count<T>::value
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,20 +70,13 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
|
|||||||
return (size + sizeof(T) - 1) / sizeof(T);
|
return (size + sizeof(T) - 1) / sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool, class = void>
|
|
||||||
struct sp_enable { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct sp_enable<true, T> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type
|
inline typename boost::enable_if_<!E &&
|
||||||
|
boost::has_trivial_destructor<T>::value>::type
|
||||||
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E &&
|
inline typename boost::enable_if_<!E &&
|
||||||
!boost::has_trivial_destructor<T>::value>::type
|
!boost::has_trivial_destructor<T>::value>::type
|
||||||
sp_array_destroy(A&, T* ptr, std::size_t size)
|
sp_array_destroy(A&, T* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
@ -163,7 +87,7 @@ sp_array_destroy(A&, T* ptr, std::size_t size)
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<E>::type
|
inline typename boost::enable_if_<E>::type
|
||||||
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
|
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
@ -198,7 +122,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E &&
|
inline typename boost::enable_if_<!E &&
|
||||||
boost::has_trivial_constructor<T>::value &&
|
boost::has_trivial_constructor<T>::value &&
|
||||||
boost::has_trivial_assign<T>::value &&
|
boost::has_trivial_assign<T>::value &&
|
||||||
boost::has_trivial_destructor<T>::value>::type
|
boost::has_trivial_destructor<T>::value>::type
|
||||||
@ -210,7 +134,7 @@ sp_array_construct(A&, T* ptr, std::size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E &&
|
inline typename boost::enable_if_<!E &&
|
||||||
boost::has_trivial_constructor<T>::value &&
|
boost::has_trivial_constructor<T>::value &&
|
||||||
boost::has_trivial_assign<T>::value &&
|
boost::has_trivial_assign<T>::value &&
|
||||||
boost::has_trivial_destructor<T>::value>::type
|
boost::has_trivial_destructor<T>::value>::type
|
||||||
@ -223,7 +147,7 @@ sp_array_construct(A&, T* ptr, std::size_t size, const T* list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E &&
|
inline typename boost::enable_if_<!E &&
|
||||||
!(boost::has_trivial_constructor<T>::value &&
|
!(boost::has_trivial_constructor<T>::value &&
|
||||||
boost::has_trivial_assign<T>::value &&
|
boost::has_trivial_assign<T>::value &&
|
||||||
boost::has_trivial_destructor<T>::value)>::type
|
boost::has_trivial_destructor<T>::value)>::type
|
||||||
@ -237,7 +161,7 @@ sp_array_construct(A& none, T* ptr, std::size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<!E &&
|
inline typename boost::enable_if_<!E &&
|
||||||
!(boost::has_trivial_constructor<T>::value &&
|
!(boost::has_trivial_constructor<T>::value &&
|
||||||
boost::has_trivial_assign<T>::value &&
|
boost::has_trivial_assign<T>::value &&
|
||||||
boost::has_trivial_destructor<T>::value)>::type
|
boost::has_trivial_destructor<T>::value)>::type
|
||||||
@ -253,7 +177,7 @@ sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<E>::type
|
inline typename boost::enable_if_<E>::type
|
||||||
sp_array_construct(A& allocator, T* ptr, std::size_t size)
|
sp_array_construct(A& allocator, T* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
sp_destroyer<E, A, T> hold(allocator, ptr);
|
sp_destroyer<E, A, T> hold(allocator, ptr);
|
||||||
@ -264,7 +188,7 @@ sp_array_construct(A& allocator, T* ptr, std::size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool E, class A, class T>
|
template<bool E, class A, class T>
|
||||||
inline typename sp_enable<E>::type
|
inline typename boost::enable_if_<E>::type
|
||||||
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
|
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
|
||||||
std::size_t count)
|
std::size_t count)
|
||||||
{
|
{
|
||||||
@ -278,11 +202,13 @@ sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class A, class T>
|
template<class A, class T>
|
||||||
inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type
|
inline typename
|
||||||
|
boost::enable_if_<boost::has_trivial_constructor<T>::value>::type
|
||||||
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
|
||||||
|
|
||||||
template<class A, class T>
|
template<class A, class T>
|
||||||
inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
|
inline typename
|
||||||
|
boost::enable_if_<!boost::has_trivial_constructor<T>::value>::type
|
||||||
sp_array_default(A& none, T* ptr, std::size_t size)
|
sp_array_default(A& none, T* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
sp_destroyer<false, A, T> hold(none, ptr);
|
sp_destroyer<false, A, T> hold(none, ptr);
|
||||||
@ -516,15 +442,15 @@ private:
|
|||||||
} /* detail */
|
} /* detail */
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared(const A& allocator, std::size_t count)
|
allocate_shared(const A& allocator, std::size_t count)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::sp_array_state<other> state;
|
typedef detail::sp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
detail::sp_counted_base* node = result.get();
|
detail::sp_counted_base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
@ -535,15 +461,15 @@ allocate_shared(const A& allocator, std::size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared(const A& allocator)
|
allocate_shared(const A& allocator)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::sp_size_array_state<other, size> state;
|
typedef detail::sp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
@ -556,38 +482,40 @@ allocate_shared(const A& allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared(const A& allocator, std::size_t count,
|
allocate_shared(const A& allocator, std::size_t count,
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::sp_array_state<other> state;
|
typedef detail::sp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
enum {
|
||||||
|
total = detail::sp_array_count<type, scalar>::value
|
||||||
|
};
|
||||||
|
std::size_t size = count * total;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
detail::sp_counted_base* node = result.get();
|
detail::sp_counted_base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
::new(static_cast<void*>(node)) base(allocator, size,
|
::new(static_cast<void*>(node)) base(allocator, size,
|
||||||
reinterpret_cast<const scalar*>(&value),
|
reinterpret_cast<const scalar*>(&value), total, start);
|
||||||
detail::sp_array_count<type>::value, start);
|
|
||||||
result.release();
|
result.release();
|
||||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared(const A& allocator,
|
allocate_shared(const A& allocator,
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::sp_size_array_state<other, size> state;
|
typedef detail::sp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state> base;
|
typedef detail::sp_array_base<state> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
@ -595,22 +523,22 @@ allocate_shared(const A& allocator,
|
|||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
::new(static_cast<void*>(node)) base(allocator, size,
|
::new(static_cast<void*>(node)) base(allocator, size,
|
||||||
reinterpret_cast<const scalar*>(&value),
|
reinterpret_cast<const scalar*>(&value),
|
||||||
detail::sp_array_count<type>::value, start);
|
detail::sp_array_count<type, scalar>::value, start);
|
||||||
result.release();
|
result.release();
|
||||||
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
|
||||||
reinterpret_cast<type*>(start), detail::shared_count(node));
|
reinterpret_cast<type*>(start), detail::shared_count(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared_noinit(const A& allocator, std::size_t count)
|
allocate_shared_noinit(const A& allocator, std::size_t count)
|
||||||
{
|
{
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
typedef typename remove_extent<T>::type type;
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
typedef detail::sp_array_state<other> state;
|
typedef detail::sp_array_state<other> state;
|
||||||
typedef detail::sp_array_base<state, false> base;
|
typedef detail::sp_array_base<state, false> base;
|
||||||
std::size_t size = count * detail::sp_array_count<type>::value;
|
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
detail::sp_counted_base* node = result.get();
|
detail::sp_counted_base* node = result.get();
|
||||||
scalar* start = detail::sp_array_start<base, scalar>(node);
|
scalar* start = detail::sp_array_start<base, scalar>(node);
|
||||||
@ -622,15 +550,15 @@ allocate_shared_noinit(const A& allocator, std::size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class A>
|
template<class T, class A>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
allocate_shared_noinit(const A& allocator)
|
allocate_shared_noinit(const A& allocator)
|
||||||
{
|
{
|
||||||
enum {
|
typedef typename remove_extent<T>::type type;
|
||||||
size = detail::sp_array_count<T>::value
|
|
||||||
};
|
|
||||||
typedef typename detail::sp_array_element<T>::type type;
|
|
||||||
typedef typename detail::sp_array_scalar<T>::type scalar;
|
typedef typename detail::sp_array_scalar<T>::type scalar;
|
||||||
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
|
||||||
|
enum {
|
||||||
|
size = detail::sp_array_count<T, scalar>::value
|
||||||
|
};
|
||||||
typedef detail::sp_size_array_state<other, size> state;
|
typedef detail::sp_size_array_state<other, size> state;
|
||||||
typedef detail::sp_array_base<state, false> base;
|
typedef detail::sp_array_base<state, false> base;
|
||||||
detail::sp_array_result<other, base> result(allocator, size);
|
detail::sp_array_result<other, base> result(allocator, size);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017 Peter Dimov
|
Copyright 2017 Peter Dimov
|
||||||
Copyright 2017 Glen Joseph Fernandes
|
Copyright 2017-2019 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@ -14,7 +14,8 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
make_local_shared()
|
make_local_shared()
|
||||||
{
|
{
|
||||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||||
@ -22,15 +23,17 @@ make_local_shared()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
make_local_shared(const typename detail::sp_array_element<T>::type& value)
|
local_shared_ptr<T> >::type
|
||||||
|
make_local_shared(const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), value);
|
detail::sp_array_scalar<T>::type>(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
make_local_shared(std::size_t size)
|
make_local_shared(std::size_t size)
|
||||||
{
|
{
|
||||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||||
@ -38,27 +41,30 @@ make_local_shared(std::size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
make_local_shared(std::size_t size,
|
make_local_shared(std::size_t size,
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
return boost::allocate_local_shared<T>(std::allocator<typename
|
return boost::allocate_local_shared<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), size, value);
|
detail::sp_array_scalar<T>::type>(), size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
make_local_shared_noinit()
|
make_local_shared_noinit()
|
||||||
{
|
{
|
||||||
return allocate_local_shared_noinit<T>(std::allocator<typename
|
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>());
|
detail::sp_array_scalar<T>::type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::lsp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
local_shared_ptr<T> >::type
|
||||||
make_local_shared_noinit(std::size_t size)
|
make_local_shared_noinit(std::size_t size)
|
||||||
{
|
{
|
||||||
return allocate_local_shared_noinit<T>(std::allocator<typename
|
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), size);
|
detail::sp_array_scalar<T>::type>(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012-2017 Glen Joseph Fernandes
|
Copyright 2012-2019 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@ -13,7 +13,7 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared()
|
make_shared()
|
||||||
{
|
{
|
||||||
return boost::allocate_shared<T>(std::allocator<typename
|
return boost::allocate_shared<T>(std::allocator<typename
|
||||||
@ -21,15 +21,15 @@ make_shared()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared(const typename detail::sp_array_element<T>::type& value)
|
make_shared(const typename remove_extent<T>::type& value)
|
||||||
{
|
{
|
||||||
return boost::allocate_shared<T>(std::allocator<typename
|
return boost::allocate_shared<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), value);
|
detail::sp_array_scalar<T>::type>(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared(std::size_t size)
|
make_shared(std::size_t size)
|
||||||
{
|
{
|
||||||
return boost::allocate_shared<T>(std::allocator<typename
|
return boost::allocate_shared<T>(std::allocator<typename
|
||||||
@ -37,27 +37,26 @@ make_shared(std::size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared(std::size_t size,
|
make_shared(std::size_t size, const typename remove_extent<T>::type& value)
|
||||||
const typename detail::sp_array_element<T>::type& value)
|
|
||||||
{
|
{
|
||||||
return boost::allocate_shared<T>(std::allocator<typename
|
return boost::allocate_shared<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), size, value);
|
detail::sp_array_scalar<T>::type>(), size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_size_array<T>::type
|
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared_noinit()
|
make_shared_noinit()
|
||||||
{
|
{
|
||||||
return allocate_shared_noinit<T>(std::allocator<typename
|
return boost::allocate_shared_noinit<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>());
|
detail::sp_array_scalar<T>::type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::sp_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
|
||||||
make_shared_noinit(std::size_t size)
|
make_shared_noinit(std::size_t size)
|
||||||
{
|
{
|
||||||
return allocate_shared_noinit<T>(std::allocator<typename
|
return boost::allocate_shared_noinit<T>(std::allocator<typename
|
||||||
detail::sp_array_scalar<T>::type>(), size);
|
detail::sp_array_scalar<T>::type>(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012-2015 Glen Joseph Fernandes
|
Copyright 2012-2019 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@ -8,59 +8,18 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
||||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/type_traits/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/is_array.hpp>
|
||||||
|
#include <boost/type_traits/is_unbounded_array.hpp>
|
||||||
|
#include <boost/type_traits/remove_extent.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct up_if_object {
|
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
|
||||||
typedef std::unique_ptr<T> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_if_object<T[]> { };
|
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
struct up_if_object<T[N]> { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_if_array { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_if_array<T[]> {
|
|
||||||
typedef std::unique_ptr<T[]> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_remove_reference {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_remove_reference<T&> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_remove_reference<T&&> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_element { };
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct up_element<T[]> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* detail */
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline typename detail::up_if_object<T>::type
|
|
||||||
make_unique()
|
make_unique()
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new T());
|
return std::unique_ptr<T>(new T());
|
||||||
@ -68,7 +27,7 @@ make_unique()
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
template<class T, class... Args>
|
template<class T, class... Args>
|
||||||
inline typename detail::up_if_object<T>::type
|
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
|
||||||
make_unique(Args&&... args)
|
make_unique(Args&&... args)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
@ -76,33 +35,33 @@ make_unique(Args&&... args)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::up_if_object<T>::type
|
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
|
||||||
make_unique(typename detail::up_remove_reference<T>::type&& value)
|
make_unique(typename remove_reference<T>::type&& value)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new T(std::move(value)));
|
return std::unique_ptr<T>(new T(std::move(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::up_if_object<T>::type
|
inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type
|
||||||
make_unique_noinit()
|
make_unique_noinit()
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new T);
|
return std::unique_ptr<T>(new T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::up_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
std::unique_ptr<T> >::type
|
||||||
make_unique(std::size_t size)
|
make_unique(std::size_t size)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new typename
|
return std::unique_ptr<T>(new typename remove_extent<T>::type[size]());
|
||||||
detail::up_element<T>::type[size]());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename detail::up_if_array<T>::type
|
inline typename enable_if_<is_unbounded_array<T>::value,
|
||||||
|
std::unique_ptr<T> >::type
|
||||||
make_unique_noinit(std::size_t size)
|
make_unique_noinit(std::size_t size)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<T>(new typename
|
return std::unique_ptr<T>(new typename remove_extent<T>::type[size]);
|
||||||
detail::up_element<T>::type[size]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* boost */
|
} /* boost */
|
||||||
|
Reference in New Issue
Block a user