forked from boostorg/smart_ptr
Update make_shared for arrays to address 2070
This updates make_shared and allocate_shared for arrays in accordance with report 2070 which requires that allocator_traits<A2>::construct(a2, ptr, ...) is used for construction and allocator_traits<A2>::destroy(a2, ptr) is used for destruction instead of placement new and destructor invocation.
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
|
||||
#include <boost/smart_ptr/detail/array_allocator.hpp>
|
||||
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
@ -24,10 +24,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::allocate_array_helper<A, T3[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::as_deleter<T3[], A> d1(allocator, n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::as_deleter<T3[], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
@ -45,10 +45,10 @@ namespace boost {
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::allocate_array_helper<A, T3[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::as_deleter<T3[N], A> d1(allocator);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::as_deleter<T3[N], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
@ -70,10 +70,10 @@ namespace boost {
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
std::size_t n1 = M * size;
|
||||
boost::detail::allocate_array_helper<A, T3[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::as_deleter<T3[], A> d1(allocator, n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::as_deleter<T3[], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
@ -95,10 +95,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
boost::detail::allocate_array_helper<A, T3[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::as_deleter<T3[N], A> d1(allocator);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::as_deleter<T3[N], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
@ -114,10 +114,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::allocate_array_helper<A, T3[]> a1(allocator, n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
@ -135,10 +135,10 @@ namespace boost {
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::allocate_array_helper<A, T3[N]> a1(allocator, &p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_size_base.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename A, typename T, typename Y = char>
|
||||
class allocate_array_helper
|
||||
: array_size_base<T> {
|
||||
using array_size_base<T>::size;
|
||||
|
||||
template<typename A_, typename T_, typename Y_>
|
||||
friend class allocate_array_helper;
|
||||
|
||||
typedef typename A::template rebind<Y> ::other A2;
|
||||
typedef typename A::template rebind<char>::other A3;
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
typedef typename A2::value_type value_type;
|
||||
typedef typename A2::pointer pointer;
|
||||
typedef typename A2::const_pointer const_pointer;
|
||||
typedef typename A2::reference reference;
|
||||
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_, type** data_)
|
||||
: allocator(allocator_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
allocate_array_helper(const A& allocator_, std::size_t size_, type** data_)
|
||||
: array_size_base<T>(size_),
|
||||
allocator(allocator_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
allocate_array_helper(const allocate_array_helper<A, T, U>& other)
|
||||
: array_size_base<T>(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<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
char* p1 = A3(allocator).allocate(size + n1, value);
|
||||
char* p2 = p1 + n1;
|
||||
while (std::size_t(p2) % a1 != 0) {
|
||||
p2--;
|
||||
}
|
||||
*data = reinterpret_cast<type*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
std::size_t a1 = boost::alignment_of<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
A3(allocator).deallocate(p1, size + 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, 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;
|
||||
type** data;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
272
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
272
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct ms_allocator_base;
|
||||
|
||||
template<typename T>
|
||||
struct ms_allocator_base<T[]> {
|
||||
ms_allocator_base(std::size_t size_)
|
||||
: size(size_ * sizeof(T)) {
|
||||
}
|
||||
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct ms_allocator_base<T[N]> {
|
||||
enum {
|
||||
size = N * sizeof(T)
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T, typename A, typename Y = char>
|
||||
class as_allocator
|
||||
: ms_allocator_base<T> {
|
||||
using ms_allocator_base<T>::size;
|
||||
|
||||
template<typename T_, typename A_, typename Y_>
|
||||
friend class as_allocator;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<Y>::other YA;
|
||||
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<char>::other CA;
|
||||
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<Y>::other YT;
|
||||
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<char>::other CT;
|
||||
#else
|
||||
typedef typename A::template rebind<Y>::other YA;
|
||||
typedef typename A::template rebind<char>::other CA;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename YT::value_type value_type;
|
||||
typedef typename YT::pointer pointer;
|
||||
typedef typename YT::const_pointer const_pointer;
|
||||
typedef typename YT::size_type size_type;
|
||||
typedef typename YT::difference_type difference_type;
|
||||
typedef Y& reference;
|
||||
typedef const Y& const_reference;
|
||||
#else
|
||||
typedef typename YA::value_type value_type;
|
||||
typedef typename YA::pointer pointer;
|
||||
typedef typename YA::const_pointer const_pointer;
|
||||
typedef typename YA::size_type size_type;
|
||||
typedef typename YA::difference_type difference_type;
|
||||
typedef typename YA::reference reference;
|
||||
typedef typename YA::const_reference const_reference;
|
||||
#endif
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef as_allocator<T, A, U> other;
|
||||
};
|
||||
|
||||
as_allocator(const A& allocator_, type** data_)
|
||||
: allocator(allocator_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
as_allocator(const A& allocator_, std::size_t size_, type** data_)
|
||||
: ms_allocator_base<T>(size_),
|
||||
allocator(allocator_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
as_allocator(const as_allocator<T, A, U>& other)
|
||||
: ms_allocator_base<T>(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<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
CA ca(allocator);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
char* p1 = CT::allocate(ca, size + n1, value);
|
||||
#else
|
||||
char* p1 = ca.allocate(size + n1, value);
|
||||
#endif
|
||||
char* p2 = p1 + n1;
|
||||
while (std::size_t(p2) % a1 != 0) {
|
||||
p2--;
|
||||
}
|
||||
*data = reinterpret_cast<type*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
std::size_t a1 = boost::alignment_of<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
CA ca(allocator);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
CT::deallocate(ca, p1, size + n1);
|
||||
#else
|
||||
ca.deallocate(p1, size + n1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void construct(pointer memory, const Y& value) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
YT::construct(allocator, memory, value);
|
||||
#else
|
||||
allocator.construct(memory, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
YT::destroy(allocator, memory);
|
||||
#else
|
||||
allocator.destroy(memory);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const as_allocator<T, A, U>& other) const {
|
||||
return allocator == other.allocator;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const as_allocator<T, A, U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
YA allocator;
|
||||
type** data;
|
||||
};
|
||||
|
||||
template<typename T, typename Y = char>
|
||||
class ms_allocator
|
||||
: ms_allocator_base<T> {
|
||||
using ms_allocator_base<T>::size;
|
||||
|
||||
template<typename T_, typename Y_>
|
||||
friend class ms_allocator;
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
typedef Y value_type;
|
||||
typedef Y* pointer;
|
||||
typedef const Y* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef Y& reference;
|
||||
typedef const Y& const_reference;
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef ms_allocator<T, U> other;
|
||||
};
|
||||
|
||||
ms_allocator(type** data_)
|
||||
: data(data_) {
|
||||
}
|
||||
|
||||
ms_allocator(std::size_t size_, type** data_)
|
||||
: ms_allocator_base<T>(size_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
ms_allocator(const ms_allocator<T, U>& other)
|
||||
: ms_allocator_base<T>(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<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y)+a1 - 1;
|
||||
void* p1 = ::operator new(n1 + size);
|
||||
char* p2 = static_cast<char*>(p1)+n1;
|
||||
while (std::size_t(p2) % a1 != 0) {
|
||||
p2--;
|
||||
}
|
||||
*data = reinterpret_cast<type*>(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 ms_allocator<T, U>&) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const ms_allocator<T, U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
type** data;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -9,17 +9,22 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct array_count_base;
|
||||
struct ms_deleter_base;
|
||||
|
||||
template<typename T>
|
||||
struct array_count_base<T[]> {
|
||||
array_count_base(std::size_t size_)
|
||||
struct ms_deleter_base<T[]> {
|
||||
ms_deleter_base(std::size_t size_)
|
||||
: size(size_) {
|
||||
}
|
||||
|
||||
@ -27,61 +32,305 @@ namespace boost {
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct array_count_base<T[N]> {
|
||||
struct ms_deleter_base<T[N]> {
|
||||
enum {
|
||||
size = N
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class array_deleter
|
||||
: array_count_base<T> {
|
||||
using array_count_base<T>::size;
|
||||
template<typename T, typename A>
|
||||
class as_deleter
|
||||
: ms_deleter_base<T> {
|
||||
using ms_deleter_base<T>::size;
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
|
||||
array_deleter()
|
||||
: object(0) {
|
||||
}
|
||||
|
||||
array_deleter(std::size_t size_)
|
||||
: array_count_base<T>(size_),
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
as_deleter(const A& allocator_)
|
||||
: allocator(allocator_),
|
||||
object(0) {
|
||||
}
|
||||
|
||||
~array_deleter() {
|
||||
if (object) {
|
||||
array_destroy(object, size);
|
||||
}
|
||||
#else
|
||||
as_deleter(const A&)
|
||||
: object(0) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
as_deleter(const A& allocator_, std::size_t size_)
|
||||
: ms_deleter_base<T>(size_),
|
||||
allocator(allocator_),
|
||||
object(0) {
|
||||
}
|
||||
#else
|
||||
as_deleter(const A&, std::size_t size_)
|
||||
: ms_deleter_base<T>(size_),
|
||||
object(0) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void init(type* memory) {
|
||||
array_init(memory, size);
|
||||
value_init(memory);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void init(type* memory, const type* value) {
|
||||
array_init<type, N>(memory, size, value);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void noinit(type* memory) {
|
||||
array_noinit(memory, size);
|
||||
value_init<N>(memory, value);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (object) {
|
||||
array_destroy(object, size);
|
||||
object = 0;
|
||||
destroy(object, size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<type>::other TA;
|
||||
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<type>::other TT;
|
||||
#endif
|
||||
|
||||
void destroy(type*, std::size_t, boost::true_type) {
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t n, boost::false_type) {
|
||||
for (std::size_t i = n; i > 0;) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::destroy(allocator, &memory[--i]);
|
||||
#else
|
||||
memory[--i].~type();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t n) {
|
||||
boost::has_trivial_destructor<type> tag;
|
||||
destroy(memory, n, tag);
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void value_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
value_init(memory, tag);
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void value_init(type* memory, const type* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i, list[i % N]);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
#endif
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i, list[i % N]);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TA allocator;
|
||||
#endif
|
||||
type* object;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ms_deleter
|
||||
: ms_deleter_base<T> {
|
||||
using ms_deleter_base<T>::size;
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
|
||||
ms_deleter()
|
||||
: object(0) {
|
||||
}
|
||||
|
||||
ms_deleter(std::size_t size_)
|
||||
: ms_deleter_base<T>(size_),
|
||||
object(0) {
|
||||
}
|
||||
|
||||
void init(type* memory) {
|
||||
value_init(memory);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void init(type* memory, const type* value) {
|
||||
value_init<N>(memory, value);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void noinit(type* memory) {
|
||||
default_init(memory);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (object) {
|
||||
destroy(object, size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void destroy(type*, std::size_t, boost::true_type) {
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t n, boost::false_type) {
|
||||
for (std::size_t i = n; i > 0;) {
|
||||
memory[--i].~type();
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t n) {
|
||||
boost::has_trivial_destructor<type> tag;
|
||||
destroy(memory, n, tag);
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void value_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
value_init(memory, tag);
|
||||
}
|
||||
|
||||
void default_init(type*, boost::true_type) {
|
||||
}
|
||||
|
||||
void default_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type;
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void default_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
default_init(memory, tag);
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void value_init(type* memory, const type* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
type* object;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_SIZE_BASE_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_SIZE_BASE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct array_size_base;
|
||||
|
||||
template<typename T>
|
||||
struct array_size_base<T[]> {
|
||||
array_size_base(std::size_t size_)
|
||||
: size(size_ * sizeof(T)) {
|
||||
}
|
||||
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct array_size_base<T[N]> {
|
||||
enum {
|
||||
size = N * sizeof(T)
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
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_value(T* memory, std::size_t size,
|
||||
boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_value(T* memory, std::size_t size,
|
||||
boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
} catch (...) {
|
||||
array_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_init(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> type;
|
||||
array_value(memory, size, type);
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
inline void array_init(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 % N]);
|
||||
}
|
||||
} 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 % N]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_default(T*, std::size_t,
|
||||
boost::true_type) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_default(T* memory, std::size_t size,
|
||||
boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
} catch (...) {
|
||||
array_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void array_noinit(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> type;
|
||||
array_default(memory, size, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2104 Glen Joseph Fernandes
|
||||
* glenfe at live dot com
|
||||
*
|
||||
* Distributed under the Boost Software License,
|
||||
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_size_base.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T, typename Y = char>
|
||||
class make_array_helper
|
||||
: array_size_base<T> {
|
||||
using array_size_base<T>::size;
|
||||
|
||||
template<typename T2, typename Y2>
|
||||
friend class make_array_helper;
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
typedef Y value_type;
|
||||
typedef Y* pointer;
|
||||
typedef const Y* const_pointer;
|
||||
typedef Y& reference;
|
||||
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(type** data_)
|
||||
: data(data_) {
|
||||
}
|
||||
|
||||
make_array_helper(std::size_t size_, type** data_)
|
||||
: array_size_base<T>(size_),
|
||||
data(data_) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
make_array_helper(const make_array_helper<T, U>& other)
|
||||
: array_size_base<T>(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<type>::value;
|
||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||
void* p1 = ::operator new(n1 + size);
|
||||
char* p2 = static_cast<char*>(p1) + n1;
|
||||
while (std::size_t(p2) % a1 != 0) {
|
||||
p2--;
|
||||
}
|
||||
*data = reinterpret_cast<type*>(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:
|
||||
type** data;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_allocator.hpp>
|
||||
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
||||
#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>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
@ -25,10 +24,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::make_array_helper<T3[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
@ -46,10 +45,10 @@ namespace boost {
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::make_array_helper<T3[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
@ -71,10 +70,10 @@ namespace boost {
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
std::size_t n1 = M * size;
|
||||
boost::detail::make_array_helper<T3[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
@ -95,10 +94,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
boost::detail::make_array_helper<T3[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
@ -114,10 +113,10 @@ namespace boost {
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::make_array_helper<T3[]> a1(n1, &p2);
|
||||
boost::detail::array_deleter<T3[]> d1(n1);
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
@ -135,10 +134,10 @@ namespace boost {
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::make_array_helper<T3[N]> a1(&p2);
|
||||
boost::detail::array_deleter<T3[N]> d1;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::array_deleter<T3[N]>* D2;
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
|
@ -97,8 +97,6 @@ template<typename U, typename A>
|
||||
<p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from
|
||||
<code>A::allocate</code>, or from the initialization of the
|
||||
object.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Remarks:</b></p>
|
||||
<blockquote>
|
||||
<p>This implementation performs no more than one memory
|
||||
@ -115,18 +113,34 @@ template<typename U, typename A>
|
||||
<p>Array elements are initialized in ascending order of their
|
||||
addresses.</p>
|
||||
<p>When a subobject of a non-array type <code>T</code> is specified to
|
||||
be initialized to a value <code>value</code>, or to
|
||||
<code>T(list...)</code>, where <code>list...</code> is a list of
|
||||
constructor arguments, <code>make_shared</code> shall perform this
|
||||
initialization via the expression <code>::new(ptr) T(value)</code>
|
||||
or <code>::new(ptr) T(list...)</code> respectively, where
|
||||
<code>ptr</code> has type <code>void*</code> and points to storage
|
||||
suitable to hold an object of type <code>T</code>.</p>
|
||||
be initialized to a value <code>value</code>,
|
||||
<code>make_shared</code> shall perform this initialization via the
|
||||
expression <code>::new(ptr) T(value)</code>, where <code>ptr</code>
|
||||
has type <code>void*</code> and points to storage suitable to hold
|
||||
an object of type <code>T</code>.</p>
|
||||
<p>When a subobject of non-array type <code>T</code> is specified to
|
||||
be initialized to a value <code>value</code>,
|
||||
<code>allocate_shared</code> shall perform this initialization via
|
||||
the expression <code>allocator_traits<A2>::construct(a2, ptr,
|
||||
value)</code>, where <code>ptr</code> points to storage suitable to
|
||||
hold an object of type <code>T</code> and <code>a2</code> of type A2
|
||||
is a rebound copy of the allocator <code>allocator</code> passed to
|
||||
<code>allocate_shared</code> such that its <code>value_type</code>
|
||||
is <code>T</code>.</p>
|
||||
<p>When a subobject of non-array type <code>T</code> is specified to
|
||||
be value-initialized, <code>make_shared</code> shall perform this
|
||||
initialization via the expression <code>::new(ptr) T()</code>, where
|
||||
<code>ptr</code> has type <code>void*</code> and points to storage
|
||||
suitable to hold an object of type <code>T</code>.</p>
|
||||
<p>When a subobject of non-array type <code>T</code> is specified to
|
||||
be value-initialized, <code>allocate_shared</code> shall perform
|
||||
this initialization via the expression
|
||||
<code>allocator_traits<A2>::construct(a2, ptr)</code>, where
|
||||
<code>ptr</code> points to storage suitable to hold an object
|
||||
of type <code>T</code> and <code>a2</code> of type A2 is a rebound
|
||||
copy of the allocator <code>allocator</code> passed to
|
||||
<code>allocate_shared</code> such that its <code>value_type</code>
|
||||
is <code>T</code>.</p>
|
||||
<p>When a subobject of non-array type <code>T</code> is specified to
|
||||
be default-initialized, <code>make_shared_noinit</code> and
|
||||
<code>allocate_shared_noinit</code> shall perform this
|
||||
@ -138,6 +152,9 @@ template<typename U, typename A>
|
||||
the initialized elements should be destroyed in the reverse order
|
||||
of their construction.</p>
|
||||
</blockquote>
|
||||
<p><b>Notes:</b> These functions will typically allocate more memory
|
||||
than <code>sizeof(U)</code> to allow for internal bookkeeping
|
||||
structures such as the reference counts.</p>
|
||||
</blockquote>
|
||||
<h2><a name="functions">Free Functions</a></h2>
|
||||
<pre>template<typename U>
|
||||
@ -149,8 +166,6 @@ template<typename U, typename A>
|
||||
object of type <code>T[size]</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
|
||||
@ -166,8 +181,6 @@ template<typename U, typename A>
|
||||
object of type <code>T[N]</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>();
|
||||
@ -184,8 +197,6 @@ template<typename U, typename A>
|
||||
is initialized to <code>value</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1);
|
||||
@ -202,8 +213,6 @@ template<typename U, typename A>
|
||||
initialized to <code>value</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1);
|
||||
@ -219,8 +228,6 @@ template<typename U, typename A>
|
||||
object of type <code>T[size]</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size);
|
||||
@ -236,8 +243,6 @@ template<typename U, typename A>
|
||||
object of type <code>T[N]</code>.</p>
|
||||
<p><b>Remarks:</b> These overloads shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>();
|
||||
|
@ -56,8 +56,6 @@ template<typename U>
|
||||
<code>r</code> is the return value.</p>
|
||||
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from
|
||||
the initialization of the object.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Remarks:</b></p>
|
||||
<blockquote>
|
||||
<p>When an object of a non-array type <code>T</code> is specified to
|
||||
@ -82,8 +80,6 @@ unique_ptr<U> make_unique(Args&&... args);</pre>
|
||||
initialized to <code>U(forward<Args>(args)...)</code>.</p>
|
||||
<p><b>Remarks:</b> This overload shall only participate in overload
|
||||
resolution when <code>U</code> is not an array type.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>unique_ptr<float> p1 = boost::make_unique<float>();
|
||||
@ -97,8 +93,6 @@ unique_ptr<U> make_unique(U&& value);</pre>
|
||||
initialized to <code>move(value)</code>.</p>
|
||||
<p><b>Remarks:</b> This overload shall only participate in overload
|
||||
resolution when <code>U</code> is not an array type.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>unique_ptr<string> p1 = boost::make_unique<string>({'a', 'b'});
|
||||
@ -112,8 +106,6 @@ unique_ptr<U> make_unique(size_t size);</pre>
|
||||
<code>T[size]</code>.</p>
|
||||
<p><b>Remarks:</b> This overload shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>unique_ptr<double[]> p1 = boost::make_unique<double[]>(4);
|
||||
@ -127,8 +119,6 @@ unique_ptr<U> make_unique_noinit();</pre>
|
||||
type <code>U</code>.</p>
|
||||
<p><b>Remarks:</b> This overload shall only participate in overload
|
||||
resolution when <code>U</code> is not an array type.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>unique_ptr<float> p1 = boost::make_unique_noinit<float>();
|
||||
@ -142,8 +132,6 @@ unique_ptr<U> make_unique_noinit(size_t size);</pre>
|
||||
type <code>T[size]</code>.</p>
|
||||
<p><b>Remarks:</b> This overload shall only participate in overload
|
||||
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p><b>Examples:</b></p>
|
||||
<blockquote>
|
||||
<pre>unique_ptr<double[]> p1 = boost::make_unique_noinit<double[]>(4);
|
||||
|
Reference in New Issue
Block a user