forked from boostorg/smart_ptr
Refactor make_array_helper and array_deleter
Reduce the amount of code in allocate_array_helper, make_array_helper, and array_deleter using the empty base class optimization technique.
This commit is contained in:
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
|
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
|
||||||
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
#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>
|
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
|
||||||
|
@ -9,45 +9,53 @@
|
|||||||
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
||||||
#define 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>
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename A, typename T, typename Y = char>
|
template<typename A, typename T, typename Y = char>
|
||||||
class allocate_array_helper;
|
class allocate_array_helper
|
||||||
|
: array_size_base<T> {
|
||||||
|
using array_size_base<T>::size;
|
||||||
|
|
||||||
template<typename A, typename T, typename Y>
|
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;
|
friend class allocate_array_helper;
|
||||||
|
|
||||||
typedef typename A::template rebind<Y> ::other A2;
|
typedef typename A::template rebind<Y> ::other A2;
|
||||||
typedef typename A::template rebind<char>::other A3;
|
typedef typename A::template rebind<char>::other A3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename A2::value_type value_type;
|
typedef typename array_inner<T>::type type;
|
||||||
typedef typename A2::pointer pointer;
|
typedef typename A2::value_type value_type;
|
||||||
typedef typename A2::const_pointer const_pointer;
|
typedef typename A2::pointer pointer;
|
||||||
typedef typename A2::reference reference;
|
typedef typename A2::const_pointer const_pointer;
|
||||||
|
typedef typename A2::reference reference;
|
||||||
typedef typename A2::const_reference const_reference;
|
typedef typename A2::const_reference const_reference;
|
||||||
typedef typename A2::size_type size_type;
|
typedef typename A2::size_type size_type;
|
||||||
typedef typename A2::difference_type difference_type;
|
typedef typename A2::difference_type difference_type;
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
struct rebind {
|
struct rebind {
|
||||||
typedef allocate_array_helper<A, T[], U> other;
|
typedef allocate_array_helper<A, T, U> other;
|
||||||
};
|
};
|
||||||
|
|
||||||
allocate_array_helper(const A& allocator_, std::size_t size_, T** data_)
|
allocate_array_helper(const A& allocator_, type** data_)
|
||||||
: allocator(allocator_),
|
: allocator(allocator_),
|
||||||
size(sizeof(T) * size_),
|
data(data_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
allocate_array_helper(const A& allocator_, std::size_t size_, type** data_)
|
||||||
|
: array_size_base<T>(size_),
|
||||||
|
allocator(allocator_),
|
||||||
data(data_) {
|
data(data_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
|
allocate_array_helper(const allocate_array_helper<A, T, U>& other)
|
||||||
: allocator(other.allocator),
|
: array_size_base<T>(other),
|
||||||
size(other.size),
|
allocator(other.allocator),
|
||||||
data(other.data) {
|
data(other.data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,22 +72,22 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pointer allocate(size_type count, const void* value = 0) {
|
pointer allocate(size_type count, const void* value = 0) {
|
||||||
std::size_t a1 = boost::alignment_of<T>::value;
|
std::size_t a1 = boost::alignment_of<type>::value;
|
||||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
char* p1 = A3(allocator).allocate(n1 + size, value);
|
char* p1 = A3(allocator).allocate(size + n1, value);
|
||||||
char* p2 = p1 + n1;
|
char* p2 = p1 + n1;
|
||||||
while (std::size_t(p2) % a1 != 0) {
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
p2--;
|
p2--;
|
||||||
}
|
}
|
||||||
*data = reinterpret_cast<T*>(p2);
|
*data = reinterpret_cast<type*>(p2);
|
||||||
return reinterpret_cast<Y*>(p1);
|
return reinterpret_cast<Y*>(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(pointer memory, size_type count) {
|
void deallocate(pointer memory, size_type count) {
|
||||||
std::size_t a1 = boost::alignment_of<T>::value;
|
std::size_t a1 = boost::alignment_of<type>::value;
|
||||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
char* p1 = reinterpret_cast<char*>(memory);
|
char* p1 = reinterpret_cast<char*>(memory);
|
||||||
A3(allocator).deallocate(p1, n1 + size);
|
A3(allocator).deallocate(p1, size + n1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct(pointer memory, const Y& value) {
|
void construct(pointer memory, const Y& value) {
|
||||||
@ -91,110 +99,18 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator==(const allocate_array_helper<A, T[], U>& other) const {
|
bool operator==(const allocate_array_helper<A, T, U>& other) const {
|
||||||
return allocator == other.allocator;
|
return allocator == other.allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
|
bool operator!=(const allocate_array_helper<A, T, U>& other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
A2 allocator;
|
A2 allocator;
|
||||||
std::size_t size;
|
type** data;
|
||||||
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;
|
|
||||||
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[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;
|
|
||||||
char* p1 = A3(allocator).allocate(n1 + N1, value);
|
|
||||||
char* p2 = p1 + n1;
|
|
||||||
while (std::size_t(p2) % a1 != 0) {
|
|
||||||
p2--;
|
|
||||||
}
|
|
||||||
*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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,38 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class array_deleter;
|
struct array_count_base;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class array_deleter<T[]> {
|
struct array_count_base<T[]> {
|
||||||
|
array_count_base(std::size_t size_)
|
||||||
|
: size(size_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
struct array_count_base<T[N]> {
|
||||||
|
enum {
|
||||||
|
size = N
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class array_deleter
|
||||||
|
: array_count_base<T> {
|
||||||
|
using array_count_base<T>::size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename array_inner<T>::type type;
|
||||||
|
|
||||||
|
array_deleter()
|
||||||
|
: object(0) {
|
||||||
|
}
|
||||||
|
|
||||||
array_deleter(std::size_t size_)
|
array_deleter(std::size_t size_)
|
||||||
: size(size_),
|
: array_count_base<T>(size_),
|
||||||
object(0) {
|
object(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,18 +56,18 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(T* memory) {
|
void init(type* memory) {
|
||||||
array_init(memory, size);
|
array_init(memory, size);
|
||||||
object = memory;
|
object = memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
void init(T* memory, const T* value) {
|
void init(type* memory, const type* value) {
|
||||||
array_init<T, N>(memory, size, value);
|
array_init<type, N>(memory, size, value);
|
||||||
object = memory;
|
object = memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void noinit(T* memory) {
|
void noinit(type* memory) {
|
||||||
array_noinit(memory, size);
|
array_noinit(memory, size);
|
||||||
object = memory;
|
object = memory;
|
||||||
}
|
}
|
||||||
@ -55,49 +80,8 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t size;
|
type* object;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t M>
|
|
||||||
void init(T* memory, const T* value) {
|
|
||||||
array_init<T, M>(memory, N, value);
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
include/boost/smart_ptr/detail/array_size_base.hpp
Normal file
37
include/boost/smart_ptr/detail/array_size_base.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
@ -9,40 +9,47 @@
|
|||||||
#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
||||||
#define 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>
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename Y = char>
|
template<typename T, typename Y = char>
|
||||||
class make_array_helper;
|
class make_array_helper
|
||||||
|
: array_size_base<T> {
|
||||||
|
using array_size_base<T>::size;
|
||||||
|
|
||||||
template<typename T, typename Y>
|
|
||||||
class make_array_helper<T[], Y> {
|
|
||||||
template<typename T2, typename Y2>
|
template<typename T2, typename Y2>
|
||||||
friend class make_array_helper;
|
friend class make_array_helper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Y value_type;
|
typedef typename array_inner<T>::type type;
|
||||||
typedef Y* pointer;
|
typedef Y value_type;
|
||||||
typedef const Y* const_pointer;
|
typedef Y* pointer;
|
||||||
typedef Y& reference;
|
typedef const Y* const_pointer;
|
||||||
typedef const Y& const_reference;
|
typedef Y& reference;
|
||||||
|
typedef const Y& const_reference;
|
||||||
typedef std::size_t size_type;
|
typedef std::size_t size_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
struct rebind {
|
struct rebind {
|
||||||
typedef make_array_helper<T[], U> other;
|
typedef make_array_helper<T, U> other;
|
||||||
};
|
};
|
||||||
|
|
||||||
make_array_helper(std::size_t size_, T** data_)
|
make_array_helper(type** data_)
|
||||||
: size(sizeof(T) * size_),
|
: data(data_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
make_array_helper(std::size_t size_, type** data_)
|
||||||
|
: array_size_base<T>(size_),
|
||||||
data(data_) {
|
data(data_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
make_array_helper(const make_array_helper<T[], U>& other)
|
make_array_helper(const make_array_helper<T, U>& other)
|
||||||
: size(other.size),
|
: array_size_base<T>(other),
|
||||||
data(other.data) {
|
data(other.data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,15 +66,15 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pointer allocate(size_type count, const void* = 0) {
|
pointer allocate(size_type count, const void* = 0) {
|
||||||
std::size_t a1 = boost::alignment_of<T>::value;
|
std::size_t a1 = boost::alignment_of<type>::value;
|
||||||
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
void* p1 = ::operator new(n1 + size);
|
void* p1 = ::operator new(n1 + size);
|
||||||
char* p2 = static_cast<char*>(p1) + n1;
|
char* p2 = static_cast<char*>(p1) + n1;
|
||||||
while (std::size_t(p2) % a1 != 0) {
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
p2--;
|
p2--;
|
||||||
}
|
}
|
||||||
*data = reinterpret_cast<T*>(p2);
|
*data = reinterpret_cast<type*>(p2);
|
||||||
return reinterpret_cast<Y*>(p1);
|
return reinterpret_cast<Y*>(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(pointer memory, size_type) {
|
void deallocate(pointer memory, size_type) {
|
||||||
@ -85,102 +92,17 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator==(const make_array_helper<T[], U>&) const {
|
bool operator==(const make_array_helper<T, U>&) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator!=(const make_array_helper<T[], U>& other) const {
|
bool operator!=(const make_array_helper<T, U>& other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t size;
|
type** data;
|
||||||
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;
|
|
||||||
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[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;
|
|
||||||
void* p1 = ::operator new(n1 + N1);
|
|
||||||
char* p2 = static_cast<char*>(p1) + n1;
|
|
||||||
while (std::size_t(p2) % a1 != 0) {
|
|
||||||
p2--;
|
|
||||||
}
|
|
||||||
*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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user