forked from boostorg/smart_ptr
Update make_shared for arrays to conform to N3870
Update make_shared and allocate_shared for arrays to be confined to the set of overloads specified in N3870.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<typename T, typename A>
|
||||
@@ -36,67 +33,27 @@ namespace boost {
|
||||
d2->init(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T, typename A, typename... Args>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
template<typename T, typename A, typename... Args>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator, Args&&... args) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator, const T& list) {
|
||||
allocate_shared(const A& allocator) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = 0;
|
||||
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init_list(p2, p3);
|
||||
d2->init(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size,
|
||||
@@ -115,12 +72,13 @@ namespace boost {
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p3 = reinterpret_cast<T3*>(&list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init_list<M>(p2, p3);
|
||||
d2->template init<M>(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator,
|
||||
@@ -139,76 +97,13 @@ namespace boost {
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p3 = reinterpret_cast<T3*>(&list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init_list<M>(p2, p3);
|
||||
d2->template init<M>(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator,
|
||||
std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = 0;
|
||||
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
|
||||
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list.begin());
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init_list(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size,
|
||||
typename boost::detail::array_base<T>::type&& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator,
|
||||
typename boost::detail::array_base<T>::type&& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator, std::size_t size) {
|
||||
@@ -226,6 +121,7 @@ namespace boost {
|
||||
d2->noinit(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -15,12 +15,15 @@ namespace boost {
|
||||
namespace detail {
|
||||
template<typename A, typename T, typename Y = char>
|
||||
class allocate_array_helper;
|
||||
|
||||
template<typename A, typename T, typename Y>
|
||||
class allocate_array_helper<A, T[], Y> {
|
||||
template<typename A9, typename T9, typename Y9>
|
||||
friend class allocate_array_helper;
|
||||
|
||||
typedef typename A::template rebind<Y> ::other A2;
|
||||
typedef typename A::template rebind<char>::other A3;
|
||||
|
||||
public:
|
||||
typedef typename A2::value_type value_type;
|
||||
typedef typename A2::pointer pointer;
|
||||
@@ -29,30 +32,37 @@ namespace boost {
|
||||
typedef typename A2::const_reference const_reference;
|
||||
typedef typename A2::size_type size_type;
|
||||
typedef typename A2::difference_type difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef allocate_array_helper<A, T[], U> other;
|
||||
};
|
||||
|
||||
allocate_array_helper(const A& allocator_, std::size_t size_, T** data_)
|
||||
: allocator(allocator_),
|
||||
size(sizeof(T) * size_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
|
||||
: allocator(other.allocator),
|
||||
size(other.size),
|
||||
data(other.data) {
|
||||
}
|
||||
|
||||
pointer address(reference value) const {
|
||||
return allocator.address(value);
|
||||
}
|
||||
|
||||
const_pointer address(const_reference value) const {
|
||||
return allocator.address(value);
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return allocator.max_size();
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* value = 0) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
@@ -64,37 +74,46 @@ namespace boost {
|
||||
*data = reinterpret_cast<T*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
A3(allocator).deallocate(p1, n1 + size);
|
||||
}
|
||||
|
||||
void construct(pointer memory, const Y& value) {
|
||||
allocator.construct(memory, value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
allocator.destroy(memory);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const allocate_array_helper<A, T[], U>& other) const {
|
||||
return allocator == other.allocator;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
A2 allocator;
|
||||
std::size_t size;
|
||||
T** data;
|
||||
};
|
||||
|
||||
template<typename A, typename T, std::size_t N, typename Y>
|
||||
class allocate_array_helper<A, T[N], Y> {
|
||||
template<typename A9, typename T9, typename Y9>
|
||||
friend class allocate_array_helper;
|
||||
|
||||
typedef typename A::template rebind<Y> ::other A2;
|
||||
typedef typename A::template rebind<char>::other A3;
|
||||
|
||||
public:
|
||||
typedef typename A2::value_type value_type;
|
||||
typedef typename A2::pointer pointer;
|
||||
@@ -103,28 +122,35 @@ namespace boost {
|
||||
typedef typename A2::const_reference const_reference;
|
||||
typedef typename A2::size_type size_type;
|
||||
typedef typename A2::difference_type difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef allocate_array_helper<A, T[N], U> other;
|
||||
};
|
||||
|
||||
allocate_array_helper(const A& allocator_, T** data_)
|
||||
: allocator(allocator_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
allocate_array_helper(const allocate_array_helper<A, T[N], U>& other)
|
||||
: allocator(other.allocator),
|
||||
data(other.data) {
|
||||
}
|
||||
|
||||
pointer address(reference value) const {
|
||||
return allocator.address(value);
|
||||
}
|
||||
|
||||
const_pointer address(const_reference value) const {
|
||||
return allocator.address(value);
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return allocator.max_size();
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* value = 0) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
@@ -136,30 +162,37 @@ namespace boost {
|
||||
*data = reinterpret_cast<T*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
A3(allocator).deallocate(p1, n1 + N1);
|
||||
}
|
||||
|
||||
void construct(pointer memory, const Y& value) {
|
||||
allocator.construct(memory, value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
allocator.destroy(memory);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const allocate_array_helper<A, T[N], U>& other) const {
|
||||
return allocator == other.allocator;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const allocate_array_helper<A, T[N], U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
N1 = N * sizeof(T)
|
||||
};
|
||||
|
||||
A2 allocator;
|
||||
T** data;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -10,12 +10,12 @@
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_forward.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
class array_deleter;
|
||||
|
||||
template<typename T>
|
||||
class array_deleter<T[]> {
|
||||
public:
|
||||
@@ -23,98 +23,77 @@ namespace boost {
|
||||
: size(size_),
|
||||
object(0) {
|
||||
}
|
||||
|
||||
~array_deleter() {
|
||||
if (object) {
|
||||
array_destroy(object, size);
|
||||
}
|
||||
}
|
||||
|
||||
void init(T* memory) {
|
||||
array_init(memory, size);
|
||||
object = memory;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
void init(T* memory, T&& value) {
|
||||
array_init_value(memory, size, sp_forward<T>(value));
|
||||
object = memory;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename... Args>
|
||||
void init(T* memory, Args&&... args) {
|
||||
array_init_args(memory, size, sp_forward<Args>(args)...);
|
||||
object = memory;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void init_list(T* memory, const T* list) {
|
||||
array_init_list(memory, size, list);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
template<std::size_t M>
|
||||
void init_list(T* memory, const T* list) {
|
||||
array_init_list<T, M>(memory, size, list);
|
||||
void init(T* memory, const T* list) {
|
||||
array_init<T, M>(memory, size, list);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void noinit(T* memory) {
|
||||
array_noinit(memory, size);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (object) {
|
||||
array_destroy(object, size);
|
||||
object = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t size;
|
||||
T* object;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
class array_deleter<T[N]> {
|
||||
public:
|
||||
array_deleter()
|
||||
: object(0) {
|
||||
}
|
||||
|
||||
~array_deleter() {
|
||||
if (object) {
|
||||
array_destroy(object, N);
|
||||
}
|
||||
}
|
||||
|
||||
void init(T* memory) {
|
||||
array_init(memory, N);
|
||||
object = memory;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
void init(T* memory, T&& value) {
|
||||
array_init_value(memory, N, sp_forward<T>(value));
|
||||
object = memory;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename... Args>
|
||||
void init(T* memory, Args&&... args) {
|
||||
array_init_args(memory, N, sp_forward<Args>(args)...);
|
||||
object = memory;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void init_list(T* memory, const T* list) {
|
||||
array_init_list(memory, N, list);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
template<std::size_t M>
|
||||
void init_list(T* memory, const T* list) {
|
||||
array_init_list<T, M>(memory, N, list);
|
||||
void init(T* memory, const T* list) {
|
||||
array_init<T, M>(memory, N, list);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void noinit(T* memory) {
|
||||
array_noinit(memory, N);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (object) {
|
||||
array_destroy(object, N);
|
||||
object = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T* object;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -17,32 +17,39 @@ namespace boost {
|
||||
struct array_base {
|
||||
typedef typename boost::remove_cv<T>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct array_base<T[]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct array_base<T[N]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct array_total {
|
||||
enum {
|
||||
size = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct array_total<T[N]> {
|
||||
enum {
|
||||
size = N * array_total<T>::size
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct array_inner;
|
||||
|
||||
template<typename T>
|
||||
struct array_inner<T[]> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct array_inner<T[N]> {
|
||||
typedef T type;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -18,25 +18,30 @@ namespace boost {
|
||||
template<typename T>
|
||||
inline void array_destroy(T*, std::size_t, boost::true_type) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_destroy(T* memory, std::size_t size, boost::false_type) {
|
||||
for (std::size_t i = size; i > 0; ) {
|
||||
memory[--i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_destroy(T* memory, std::size_t size) {
|
||||
boost::has_trivial_destructor<T> type;
|
||||
array_destroy(memory, size, type);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_init(T* memory, std::size_t size, boost::true_type) {
|
||||
inline void array_value(T* memory, std::size_t size, boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
memory[i] = T();
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_init(T* memory, std::size_t size, boost::false_type) {
|
||||
inline void array_value(T* memory, std::size_t size, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
@@ -55,77 +60,15 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_init(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> type;
|
||||
array_init(memory, size, type);
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T>
|
||||
inline void array_init_value(T* memory, std::size_t size, T&& value) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(value);
|
||||
}
|
||||
} catch (...) {
|
||||
array_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename T, typename... Args>
|
||||
inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(args...);
|
||||
}
|
||||
} catch (...) {
|
||||
array_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(args...);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
template<typename T>
|
||||
inline void array_init_list(T* memory, std::size_t size, const T* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(list[i]);
|
||||
}
|
||||
} catch (...) {
|
||||
array_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(list[i]);
|
||||
}
|
||||
#endif
|
||||
array_value(memory, size, type);
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
inline void array_init_list(T* memory, std::size_t size, const T* list) {
|
||||
inline void array_init(T* memory, std::size_t size, const T* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
@@ -144,11 +87,13 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_noinit(T*, std::size_t, boost::true_type) {
|
||||
inline void array_default(T*, std::size_t, boost::true_type) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_noinit(T* memory, std::size_t size, boost::false_type) {
|
||||
inline void array_default(T* memory, std::size_t size, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
@@ -167,10 +112,11 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_noinit(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> type;
|
||||
array_noinit(memory, size, type);
|
||||
array_default(memory, size, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2104 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -15,10 +15,12 @@ namespace boost {
|
||||
namespace detail {
|
||||
template<typename T, typename Y = char>
|
||||
class make_array_helper;
|
||||
|
||||
template<typename T, typename Y>
|
||||
class make_array_helper<T[], Y> {
|
||||
template<typename T2, typename Y2>
|
||||
friend class make_array_helper;
|
||||
|
||||
public:
|
||||
typedef Y value_type;
|
||||
typedef Y* pointer;
|
||||
@@ -27,28 +29,35 @@ namespace boost {
|
||||
typedef const Y& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef make_array_helper<T[], U> other;
|
||||
};
|
||||
|
||||
make_array_helper(std::size_t size_, T** data_)
|
||||
: size(sizeof(T) * size_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
make_array_helper(const make_array_helper<T[], U>& other)
|
||||
: size(other.size),
|
||||
data(other.data) {
|
||||
}
|
||||
|
||||
pointer address(reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return static_cast<std::size_t>(-1) / sizeof(Y);
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* = 0) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
@@ -60,33 +69,41 @@ namespace boost {
|
||||
*data = reinterpret_cast<T*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type) {
|
||||
void* p1 = memory;
|
||||
::operator delete(p1);
|
||||
}
|
||||
|
||||
void construct(pointer memory, const Y& value) {
|
||||
void* p1 = memory;
|
||||
::new(p1) Y(value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
memory->~Y();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const make_array_helper<T[], U>&) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const make_array_helper<T[], U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t size;
|
||||
T** data;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N, typename Y>
|
||||
class make_array_helper<T[N], Y> {
|
||||
template<typename T2, typename Y2>
|
||||
friend class make_array_helper;
|
||||
|
||||
public:
|
||||
typedef Y value_type;
|
||||
typedef Y* pointer;
|
||||
@@ -95,26 +112,33 @@ namespace boost {
|
||||
typedef const Y& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef make_array_helper<T[N], U> other;
|
||||
};
|
||||
|
||||
make_array_helper(T** data_)
|
||||
: data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
make_array_helper(const make_array_helper<T[N], U>& other)
|
||||
: data(other.data) {
|
||||
}
|
||||
|
||||
pointer address(reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return static_cast<std::size_t>(-1) / sizeof(Y);
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* = 0) {
|
||||
std::size_t a1 = boost::alignment_of<T>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
@@ -126,29 +150,36 @@ namespace boost {
|
||||
*data = reinterpret_cast<T*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type) {
|
||||
void* p1 = memory;
|
||||
::operator delete(p1);
|
||||
}
|
||||
|
||||
void construct(pointer memory, const Y& value) {
|
||||
void* p1 = memory;
|
||||
::new(p1) Y(value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
memory->~Y();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const make_array_helper<T[N], U>&) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const make_array_helper<T[N], U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
N1 = N * sizeof(T)
|
||||
};
|
||||
|
||||
T** data;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -15,12 +15,15 @@ namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct sp_if_array;
|
||||
|
||||
template<typename T>
|
||||
struct sp_if_array<T[]> {
|
||||
typedef boost::shared_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct sp_if_size_array;
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct sp_if_size_array<T[N]> {
|
||||
typedef boost::shared_ptr<T[N]> type;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/make_array_helper.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<typename T>
|
||||
@@ -36,67 +33,27 @@ namespace boost {
|
||||
d2->init(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T, typename... Args>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size, Args&&... args) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared(Args&&... args) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared(const T& list) {
|
||||
make_shared() {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = 0;
|
||||
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init_list(p2, p3);
|
||||
d2->init(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size,
|
||||
@@ -115,12 +72,13 @@ namespace boost {
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p3 = reinterpret_cast<T3*>(&list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init_list<M>(p2, p3);
|
||||
d2->template init<M>(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared(const typename boost::detail::array_inner<T>::type& list) {
|
||||
@@ -138,74 +96,13 @@ namespace boost {
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list);
|
||||
p3 = reinterpret_cast<T3*>(&list);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init_list<M>(p2, p3);
|
||||
d2->template init<M>(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = 0;
|
||||
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
|
||||
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p3 = reinterpret_cast<T3*>(list.begin());
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init_list(p2, p3);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size,
|
||||
typename boost::detail::array_base<T>::type&& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T2[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared(typename boost::detail::array_base<T>::type&& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T2[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared_noinit(std::size_t size) {
|
||||
@@ -223,6 +120,7 @@ namespace boost {
|
||||
d2->noinit(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared_noinit() {
|
||||
|
||||
Reference in New Issue
Block a user