annotate DEPENDENCIES/generic/include/boost/smart_ptr/detail/array_allocator.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 /*
Chris@102 2 * Copyright (c) 2012-2014 Glen Joseph Fernandes
Chris@102 3 * glenfe at live dot com
Chris@102 4 *
Chris@102 5 * Distributed under the Boost Software License,
Chris@102 6 * Version 1.0. (See accompanying file LICENSE_1_0.txt
Chris@102 7 * or copy at http://boost.org/LICENSE_1_0.txt)
Chris@102 8 */
Chris@102 9 #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
Chris@102 10 #define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
Chris@102 11
Chris@102 12 #include <boost/align/align.hpp>
Chris@102 13 #include <boost/smart_ptr/detail/array_traits.hpp>
Chris@102 14 #include <boost/smart_ptr/detail/array_utility.hpp>
Chris@102 15 #include <boost/type_traits/alignment_of.hpp>
Chris@102 16
Chris@102 17 namespace boost {
Chris@102 18 namespace detail {
Chris@102 19 struct ms_init_tag { };
Chris@102 20 struct ms_noinit_tag { };
Chris@102 21
Chris@102 22 template<class T>
Chris@102 23 struct ms_allocator_state;
Chris@102 24
Chris@102 25 template<class T>
Chris@102 26 struct ms_allocator_state<T[]> {
Chris@102 27 typedef typename array_base<T>::type type;
Chris@102 28
Chris@102 29 ms_allocator_state(std::size_t size_,
Chris@102 30 type** result_)
Chris@102 31 : size(size_ * array_total<T>::size),
Chris@102 32 result(result_) {
Chris@102 33 }
Chris@102 34
Chris@102 35 std::size_t size;
Chris@102 36
Chris@102 37 union {
Chris@102 38 type** result;
Chris@102 39 type* object;
Chris@102 40 };
Chris@102 41 };
Chris@102 42
Chris@102 43 template<class T, std::size_t N>
Chris@102 44 struct ms_allocator_state<T[N]> {
Chris@102 45 typedef typename array_base<T>::type type;
Chris@102 46
Chris@102 47 ms_allocator_state(type** result_)
Chris@102 48 : result(result_) {
Chris@102 49 }
Chris@102 50
Chris@102 51 enum {
Chris@102 52 size = array_total<T[N]>::size
Chris@102 53 };
Chris@102 54
Chris@102 55 union {
Chris@102 56 type** result;
Chris@102 57 type* object;
Chris@102 58 };
Chris@102 59 };
Chris@102 60
Chris@102 61 template<class A, class T, class R>
Chris@102 62 class as_allocator
Chris@102 63 : public A {
Chris@102 64 template<class A_, class T_, class R_>
Chris@102 65 friend class as_allocator;
Chris@102 66
Chris@102 67 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
Chris@102 68 typedef std::allocator_traits<A> AT;
Chris@102 69 typedef typename AT::template rebind_alloc<char> CA;
Chris@102 70 typedef typename AT::template rebind_traits<char> CT;
Chris@102 71 #else
Chris@102 72 typedef typename A::template rebind<char>::other CA;
Chris@102 73 #endif
Chris@102 74
Chris@102 75 public:
Chris@102 76 typedef A allocator_type;
Chris@102 77
Chris@102 78 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
Chris@102 79 typedef typename AT::value_type value_type;
Chris@102 80 typedef typename AT::pointer pointer;
Chris@102 81 typedef typename AT::const_pointer const_pointer;
Chris@102 82 typedef typename AT::void_pointer void_pointer;
Chris@102 83 typedef typename AT::const_void_pointer const_void_pointer;
Chris@102 84 typedef typename AT::size_type size_type;
Chris@102 85 typedef typename AT::difference_type difference_type;
Chris@102 86 #else
Chris@102 87 typedef typename A::value_type value_type;
Chris@102 88 typedef typename A::pointer pointer;
Chris@102 89 typedef typename A::const_pointer const_pointer;
Chris@102 90 typedef typename A::size_type size_type;
Chris@102 91 typedef typename A::difference_type difference_type;
Chris@102 92 typedef typename A::reference reference;
Chris@102 93 typedef typename A::const_reference const_reference;
Chris@102 94 typedef void* void_pointer;
Chris@102 95 typedef const void* const_void_pointer;
Chris@102 96 #endif
Chris@102 97
Chris@102 98 template<class U>
Chris@102 99 struct rebind {
Chris@102 100 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
Chris@102 101 typedef as_allocator<typename AT::
Chris@102 102 template rebind_alloc<U>, T, R> other;
Chris@102 103 #else
Chris@102 104 typedef as_allocator<typename A::
Chris@102 105 template rebind<U>::other, T, R> other;
Chris@102 106 #endif
Chris@102 107 };
Chris@102 108
Chris@102 109 typedef typename array_base<T>::type type;
Chris@102 110
Chris@102 111 as_allocator(const A& allocator_, type** result)
Chris@102 112 : A(allocator_),
Chris@102 113 data(result) {
Chris@102 114 }
Chris@102 115
Chris@102 116 as_allocator(const A& allocator_, std::size_t size,
Chris@102 117 type** result)
Chris@102 118 : A(allocator_),
Chris@102 119 data(size, result) {
Chris@102 120 }
Chris@102 121
Chris@102 122 template<class U>
Chris@102 123 as_allocator(const as_allocator<U, T, R>& other)
Chris@102 124 : A(other.allocator()),
Chris@102 125 data(other.data) {
Chris@102 126 }
Chris@102 127
Chris@102 128 pointer allocate(size_type count, const_void_pointer = 0) {
Chris@102 129 enum {
Chris@102 130 M = boost::alignment_of<type>::value
Chris@102 131 };
Chris@102 132 std::size_t n1 = count * sizeof(value_type);
Chris@102 133 std::size_t n2 = data.size * sizeof(type);
Chris@102 134 std::size_t n3 = n2 + M;
Chris@102 135 CA ca(allocator());
Chris@102 136 void* p1 = ca.allocate(n1 + n3);
Chris@102 137 void* p2 = static_cast<char*>(p1) + n1;
Chris@102 138 (void)boost::alignment::align(M, n2, p2, n3);
Chris@102 139 *data.result = static_cast<type*>(p2);
Chris@102 140 return static_cast<value_type*>(p1);
Chris@102 141 }
Chris@102 142
Chris@102 143 void deallocate(pointer memory, size_type count) {
Chris@102 144 enum {
Chris@102 145 M = boost::alignment_of<type>::value
Chris@102 146 };
Chris@102 147 std::size_t n1 = count * sizeof(value_type);
Chris@102 148 std::size_t n2 = data.size * sizeof(type) + M;
Chris@102 149 char* p1 = reinterpret_cast<char*>(memory);
Chris@102 150 CA ca(allocator());
Chris@102 151 ca.deallocate(p1, n1 + n2);
Chris@102 152 }
Chris@102 153
Chris@102 154 const A& allocator() const {
Chris@102 155 return static_cast<const A&>(*this);
Chris@102 156 }
Chris@102 157
Chris@102 158 A& allocator() {
Chris@102 159 return static_cast<A&>(*this);
Chris@102 160 }
Chris@102 161
Chris@102 162 void set(type* memory) {
Chris@102 163 data.object = memory;
Chris@102 164 }
Chris@102 165
Chris@102 166 void operator()() {
Chris@102 167 if (data.object) {
Chris@102 168 R tag;
Chris@102 169 release(tag);
Chris@102 170 }
Chris@102 171 }
Chris@102 172
Chris@102 173 private:
Chris@102 174 void release(ms_init_tag) {
Chris@102 175 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
Chris@102 176 as_destroy(allocator(), data.object, data.size);
Chris@102 177 #else
Chris@102 178 ms_destroy(data.object, data.size);
Chris@102 179 #endif
Chris@102 180 }
Chris@102 181
Chris@102 182 void release(ms_noinit_tag) {
Chris@102 183 ms_destroy(data.object, data.size);
Chris@102 184 }
Chris@102 185
Chris@102 186 ms_allocator_state<T> data;
Chris@102 187 };
Chris@102 188
Chris@102 189 template<class A1, class A2, class T, class R>
Chris@102 190 bool operator==(const as_allocator<A1, T, R>& a1,
Chris@102 191 const as_allocator<A2, T, R>& a2) {
Chris@102 192 return a1.allocator() == a2.allocator();
Chris@102 193 }
Chris@102 194
Chris@102 195 template<class A1, class A2, class T, class R>
Chris@102 196 bool operator!=(const as_allocator<A1, T, R>& a1,
Chris@102 197 const as_allocator<A2, T, R>& a2) {
Chris@102 198 return a1.allocator() != a2.allocator();
Chris@102 199 }
Chris@102 200
Chris@102 201 template<class T, class Y = char>
Chris@102 202 class ms_allocator;
Chris@102 203
Chris@102 204 template<class T, class Y>
Chris@102 205 class ms_allocator {
Chris@102 206 template<class T_, class Y_>
Chris@102 207 friend class ms_allocator;
Chris@102 208
Chris@102 209 public:
Chris@102 210 typedef typename array_base<T>::type type;
Chris@102 211
Chris@102 212 typedef Y value_type;
Chris@102 213 typedef Y* pointer;
Chris@102 214 typedef const Y* const_pointer;
Chris@102 215 typedef std::size_t size_type;
Chris@102 216 typedef std::ptrdiff_t difference_type;
Chris@102 217 typedef Y& reference;
Chris@102 218 typedef const Y& const_reference;
Chris@102 219
Chris@102 220 template<class U>
Chris@102 221 struct rebind {
Chris@102 222 typedef ms_allocator<T, U> other;
Chris@102 223 };
Chris@102 224
Chris@102 225 ms_allocator(type** result)
Chris@102 226 : data(result) {
Chris@102 227 }
Chris@102 228
Chris@102 229 ms_allocator(std::size_t size, type** result)
Chris@102 230 : data(size, result) {
Chris@102 231 }
Chris@102 232
Chris@102 233 template<class U>
Chris@102 234 ms_allocator(const ms_allocator<T, U>& other)
Chris@102 235 : data(other.data) {
Chris@102 236 }
Chris@102 237
Chris@102 238 pointer allocate(size_type count, const void* = 0) {
Chris@102 239 enum {
Chris@102 240 M = boost::alignment_of<type>::value
Chris@102 241 };
Chris@102 242 std::size_t n1 = count * sizeof(Y);
Chris@102 243 std::size_t n2 = data.size * sizeof(type);
Chris@102 244 std::size_t n3 = n2 + M;
Chris@102 245 void* p1 = ::operator new(n1 + n3);
Chris@102 246 void* p2 = static_cast<char*>(p1) + n1;
Chris@102 247 (void)boost::alignment::align(M, n2, p2, n3);
Chris@102 248 *data.result = static_cast<type*>(p2);
Chris@102 249 return static_cast<Y*>(p1);
Chris@102 250 }
Chris@102 251
Chris@102 252 void deallocate(pointer memory, size_type) {
Chris@102 253 void* p1 = memory;
Chris@102 254 ::operator delete(p1);
Chris@102 255 }
Chris@102 256
Chris@102 257 #if defined(BOOST_NO_CXX11_ALLOCATOR)
Chris@102 258 pointer address(reference value) const {
Chris@102 259 return &value;
Chris@102 260 }
Chris@102 261
Chris@102 262 const_pointer address(const_reference value) const {
Chris@102 263 return &value;
Chris@102 264 }
Chris@102 265
Chris@102 266 size_type max_size() const {
Chris@102 267 enum {
Chris@102 268 N = static_cast<std::size_t>(-1) / sizeof(Y)
Chris@102 269 };
Chris@102 270 return N;
Chris@102 271 }
Chris@102 272
Chris@102 273 void construct(pointer memory, const_reference value) {
Chris@102 274 void* p1 = memory;
Chris@102 275 ::new(p1) Y(value);
Chris@102 276 }
Chris@102 277
Chris@102 278 void destroy(pointer memory) {
Chris@102 279 (void)memory;
Chris@102 280 memory->~Y();
Chris@102 281 }
Chris@102 282 #endif
Chris@102 283
Chris@102 284 void set(type* memory) {
Chris@102 285 data.object = memory;
Chris@102 286 }
Chris@102 287
Chris@102 288 void operator()() {
Chris@102 289 if (data.object) {
Chris@102 290 ms_destroy(data.object, data.size);
Chris@102 291 }
Chris@102 292 }
Chris@102 293
Chris@102 294 private:
Chris@102 295 ms_allocator_state<T> data;
Chris@102 296 };
Chris@102 297
Chris@102 298 template<class T, class Y1, class Y2>
Chris@102 299 bool operator==(const ms_allocator<T, Y1>&,
Chris@102 300 const ms_allocator<T, Y2>&) {
Chris@102 301 return true;
Chris@102 302 }
Chris@102 303
Chris@102 304 template<class T, class Y1, class Y2>
Chris@102 305 bool operator!=(const ms_allocator<T, Y1>&,
Chris@102 306 const ms_allocator<T, Y2>&) {
Chris@102 307 return false;
Chris@102 308 }
Chris@102 309
Chris@102 310 class ms_in_allocator_tag {
Chris@102 311 public:
Chris@102 312 void operator()(const void*) {
Chris@102 313 }
Chris@102 314 };
Chris@102 315 }
Chris@102 316 }
Chris@102 317
Chris@102 318 #endif