blob: 11051373143e86c13d070694ec55d43a431a606b [file] [log] [blame]
Jeff Thompsonf7d49942013-08-01 16:47:40 -07001/*
2 * Copyright (c) 2012 Glen Joseph Fernandes
3 * glenfe at live dot com
4 *
5 * Distributed under the Boost Software License,
6 * Version 1.0. (See accompanying file LICENSE_1_0.txt
7 * or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
10#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
11
Jeff Thompson2277ce52013-08-01 17:34:11 -070012#include <ndnboost/type_traits/alignment_of.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070013
14namespace ndnboost {
15 namespace detail {
16 template<typename T, typename Y = char>
17 class make_array_helper;
18 template<typename T, typename Y>
19 class make_array_helper<T[], Y> {
20 template<typename T2, typename Y2>
21 friend class make_array_helper;
22 public:
23 typedef Y value_type;
24 typedef Y* pointer;
25 typedef const Y* const_pointer;
26 typedef Y& reference;
27 typedef const Y& const_reference;
28 typedef std::size_t size_type;
29 typedef ptrdiff_t difference_type;
30 template<typename U>
31 struct rebind {
32 typedef make_array_helper<T[], U> other;
33 };
Jeff Thompsona28eed82013-08-22 16:21:10 -070034 make_array_helper(std::size_t size_, T** data_)
35 : size(sizeof(T) * size_),
36 data(data_) {
Jeff Thompsonf7d49942013-08-01 16:47:40 -070037 }
38 template<class U>
39 make_array_helper(const make_array_helper<T[], U>& other)
40 : size(other.size),
41 data(other.data) {
42 }
43 pointer address(reference value) const {
44 return &value;
45 }
46 const_pointer address(const_reference value) const {
47 return &value;
48 }
49 size_type max_size() const {
50 return static_cast<std::size_t>(-1) / sizeof(Y);
51 }
52 pointer allocate(size_type count, const void* = 0) {
53 std::size_t a1 = ndnboost::alignment_of<T>::value;
54 std::size_t n1 = count * sizeof(Y) + a1 - 1;
55 void* p1 = ::operator new(n1 + size);
56 char* p2 = static_cast<char*>(p1) + n1;
57 while (std::size_t(p2) % a1 != 0) {
58 p2--;
59 }
60 *data = reinterpret_cast<T*>(p2);
61 return reinterpret_cast<Y*>(p1);
62 }
63 void deallocate(pointer memory, size_type) {
64 void* p1 = memory;
65 ::operator delete(p1);
66 }
67 void construct(pointer memory, const Y& value) {
68 void* p1 = memory;
69 ::new(p1) Y(value);
70 }
71 void destroy(pointer memory) {
72 memory->~Y();
73 }
74 template<typename U>
Jeff Thompsona28eed82013-08-22 16:21:10 -070075 bool operator==(const make_array_helper<T[], U>&) const {
Jeff Thompsonf7d49942013-08-01 16:47:40 -070076 return true;
77 }
78 template<typename U>
79 bool operator!=(const make_array_helper<T[], U>& other) const {
80 return !(*this == other);
81 }
82 private:
83 std::size_t size;
84 T** data;
85 };
86 template<typename T, std::size_t N, typename Y>
87 class make_array_helper<T[N], Y> {
88 template<typename T2, typename Y2>
89 friend class make_array_helper;
90 public:
91 typedef Y value_type;
92 typedef Y* pointer;
93 typedef const Y* const_pointer;
94 typedef Y& reference;
95 typedef const Y& const_reference;
96 typedef std::size_t size_type;
97 typedef ptrdiff_t difference_type;
98 template<typename U>
99 struct rebind {
100 typedef make_array_helper<T[N], U> other;
101 };
Jeff Thompsona28eed82013-08-22 16:21:10 -0700102 make_array_helper(T** data_)
103 : data(data_) {
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700104 }
105 template<class U>
106 make_array_helper(const make_array_helper<T[N], U>& other)
107 : data(other.data) {
108 }
109 pointer address(reference value) const {
110 return &value;
111 }
112 const_pointer address(const_reference value) const {
113 return &value;
114 }
115 size_type max_size() const {
116 return static_cast<std::size_t>(-1) / sizeof(Y);
117 }
118 pointer allocate(size_type count, const void* = 0) {
119 std::size_t a1 = ndnboost::alignment_of<T>::value;
120 std::size_t n1 = count * sizeof(Y) + a1 - 1;
121 void* p1 = ::operator new(n1 + N1);
122 char* p2 = static_cast<char*>(p1) + n1;
123 while (std::size_t(p2) % a1 != 0) {
124 p2--;
125 }
126 *data = reinterpret_cast<T*>(p2);
127 return reinterpret_cast<Y*>(p1);
128 }
129 void deallocate(pointer memory, size_type) {
130 void* p1 = memory;
131 ::operator delete(p1);
132 }
133 void construct(pointer memory, const Y& value) {
134 void* p1 = memory;
135 ::new(p1) Y(value);
136 }
137 void destroy(pointer memory) {
138 memory->~Y();
139 }
140 template<typename U>
Jeff Thompsona28eed82013-08-22 16:21:10 -0700141 bool operator==(const make_array_helper<T[N], U>&) const {
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700142 return true;
143 }
144 template<typename U>
145 bool operator!=(const make_array_helper<T[N], U>& other) const {
146 return !(*this == other);
147 }
148 private:
149 enum {
150 N1 = N * sizeof(T)
151 };
152 T** data;
153 };
154 }
155}
156
157#endif