Adobe Source Libraries 2.0.6
A collection of C++ libraries.
Loading...
Searching...
No Matches
memory.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6/**************************************************************************************************/
7
8#ifndef ADOBE_MEMORY_HPP
9#define ADOBE_MEMORY_HPP
10
11#include <adobe/config.hpp>
12
13#include <cassert>
14#include <utility>
15
16#include <adobe/conversion.hpp>
17#include <adobe/functional.hpp>
18#include <adobe/memory_fwd.hpp>
19
20/**************************************************************************************************/
21
22namespace adobe {
23
24/**************************************************************************************************/
25
30
31template <typename T>
32struct empty_ptr;
33
34template <typename T>
35struct empty_ptr<T*> {
36 bool operator()(const T* x) const throw() { return x == NULL; }
37};
38
39
40template <typename T>
41struct empty_ptr<T (*)[]> {
42 bool operator()(const T* x) const throw() { return x == NULL; }
43};
44
45/*
46 REVISIT (sparent) : This is a hack - the new delete_ptr is not a template
47 auto_resource is too complicated with the traits classes -
48 provide a delete op as a tempalte argument?
49*/
50
51template <typename T>
53
54template <typename T>
55struct delete_ptr_trait<T*> {
56 void operator()(const T* x) const { delete x; }
57};
58
59template <typename T>
60struct delete_ptr_trait<T (*)[]> {
61 void operator()(const T* x) const { delete[] x; }
62};
63
65
66/**************************************************************************************************/
67
68template <typename X, class Traits>
69class auto_resource;
70
71template <typename ptrT>
73
75template <typename T>
76struct ptr_traits<T (*)[]> {
77 typedef T element_type;
78 typedef T* pointer_type;
79 typedef const T* const_pointer_type;
80
81 template <class U>
82 struct rebind {
84 };
85 enum { is_array = true };
86
87 static void delete_ptr(pointer_type x) throw() { delete_ptr_trait<T(*)[]>()(x); }
88 static bool empty_ptr(const_pointer_type x) throw() { return adobe::empty_ptr<T(*)[]>()(x); }
89};
90
95
153template <typename T>
154struct ptr_traits<T*> {
155 typedef T element_type;
156 typedef T* pointer_type;
158
159 template <class U>
160 struct rebind {
162 };
163 enum { is_array = false };
164
165 static void delete_ptr(pointer_type x) throw() { adobe::delete_ptr_trait<T*>()(x); }
166 static bool empty_ptr(const_pointer_type x) throw() { return adobe::empty_ptr<T*>()(x); }
167};
168
169/**************************************************************************************************/
170
171#ifndef NO_DOCUMENTATION
172
173/*
174 REVISIT (sparent) : This could use boost::static_assert but it doesn't seem worth adding a
175 boost dependency just for this case.
176*/
177
178namespace implementation {
179template <bool x>
180struct adobe_static_assert;
181template <>
182struct adobe_static_assert<true> {};
183} // namespace implementation
184
185#endif
186
187/**************************************************************************************************/
188
189/* REVISIT (sparent) : auto_resource should become unique_resource. */
190
200
201template <typename X, class Traits = ptr_traits<X>>
203 struct clear_type {};
204 operator int() const;
205
206public:
207 typedef Traits traits_type;
208 typedef typename traits_type::element_type element_type;
209 typedef typename traits_type::pointer_type pointer_type;
210
211 // 20.4.5.1 construct/copy/destroy:
212 explicit auto_resource(pointer_type p = 0) throw();
213
215 template <typename Y>
216 auto_resource(const auto_resource<Y, typename traits_type::template rebind<Y>::other>&) throw();
217
218 auto_resource& operator=(auto_resource&) throw();
219 template <typename Y>
221 operator=(auto_resource<Y, typename traits_type::template rebind<Y>::other>) throw();
222
223 ~auto_resource() throw();
224
225 // assignment from NULL
226 auto_resource& operator=(const clear_type*) throw();
227
228 // 20.4.5.2 members:
229 pointer_type get() const throw();
230 pointer_type release() throw();
231 void reset(pointer_type p = 0) throw();
232
233 // Safe bool conversion (private int conversion prevents unsafe use)
234 operator bool() const throw() { return (pointer_m != NULL); }
235 bool operator!() const throw();
236
237private:
238/*
239 20.4.5.3 conversions:
240
241 NOTE (sparent) : As per the recommendations on standard issue 463 the conversion
242 operators through auto_ptr_ref have been removed in favor of using this conditional
243 enabled trick.
244
245 http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463
246*/
247// REVISIT: VC 2003 internal compiler error workaround. Some misues of auto_resource will go
248// undetected under MSVC until fixed.
249// REVISIT: Failes with incomplete types with Apple's LLVM 3.0 compiler.
250#if 0
251#ifndef BOOST_MSVC
252 template <typename Y> struct error_on_const_auto_type;
253 template <typename Y> struct error_on_const_auto_type<auto_resource<Y, typename traits_type::template rebind<Y>::other> const>
254 { typedef typename auto_resource<Y, typename traits_type::template rebind<Y>::other>::const_auto_type_is_not_allowed type; };
255
256 template <class Y>
257 auto_resource(Y& rhs, typename error_on_const_auto_type<Y>::type = 0);
258#endif
259#endif
260 pointer_type pointer_m;
261};
262
263/**************************************************************************************************/
264
265template <typename X, class Traits>
266inline auto_resource<X, Traits>::auto_resource(pointer_type p) throw() : pointer_m(p) {}
267
268template <typename X, class Traits>
269inline auto_resource<X, Traits>::auto_resource(auto_resource& x) throw() : pointer_m(x.release()) {}
270
271template <typename X, class Traits>
272template <typename Y>
274 auto_resource<Y, typename traits_type::template rebind<Y>::other> const& x) throw()
276 .release()) {}
277
278template <typename X, class Traits>
280 reset(x.release());
281 return *this;
282}
283
284template <typename X, class Traits>
285template <typename Y>
287 auto_resource<Y, typename traits_type::template rebind<Y>::other> x) throw() {
288 reset(x.release());
289 return *this;
290}
291
292template <typename X, class Traits>
294 traits_type::delete_ptr(pointer_m);
295}
296
297/**************************************************************************************************/
298
299template <typename X, class Traits>
301 reset();
302 return *this;
303}
304
305/**************************************************************************************************/
306
307template <typename X, class Traits>
309 throw() {
310 return pointer_m;
311}
312
313template <typename X, class Traits>
315 pointer_type result(pointer_m);
316 pointer_m = NULL;
317 return result;
318}
319
320template <typename X, class Traits>
322 if (pointer_m != p) {
323 traits_type::delete_ptr(pointer_m);
324 pointer_m = p;
325 }
326}
327
328/**************************************************************************************************/
329
330template <typename X, class Traits>
331inline bool auto_resource<X, Traits>::operator!() const throw() {
332 return !pointer_m;
333}
334
335/**************************************************************************************************/
336
337template <typename T> // T models Regular
338inline void destroy(T* p) {
339 p->~T();
340}
341
342/*
343 https://en.cppreference.com/w/cpp/memory/construct_at
344*/
345
346template <class T, class... Args>
347T* construct_at(T* p, Args&&... args) {
348 return ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
349}
350
351template <typename T, typename U> // T models Regular
352[[deprecated("Use adobe::construct_at(p, x)")]] constexpr auto construct(T* p, U&& x) {
353 return construct_at(p, std::forward<U>(x));
354}
355
356template <typename T> // T models Regular
357[[deprecated("Use adobe::construct_at(p)")]] constexpr auto construct(T* p) {
358 return construct_at(p);
359}
360
361template <typename F> // F models ForwardIterator
362inline void destroy(F f, F l) {
363 while (f != l) {
364 destroy(&*f);
365 ++f;
366 }
367}
368
369/**************************************************************************************************/
370
374template <typename I, // I models InputIterator
375 typename F>
376// F models ForwardIterator
377F uninitialized_move(I f, I l, F r) {
378 while (f != l) {
379 adobe::construct(&*r, std::move(*f));
380 ++f;
381 ++r;
382 }
383 return r;
384}
385
386/**************************************************************************************************/
387
388inline namespace version_1 {
389
392
394 void* (*new_)(std::size_t);
395 void (*delete_)(void*);
396};
397
399
400template <>
401class capture_allocator<void> {
402public:
403 void* pointer;
404 typedef const void* const_pointer;
405 typedef void value_type;
406 template <class U>
407 struct rebind {
409 };
410
411 friend inline bool operator==(const capture_allocator&, const capture_allocator&) {
412 return true;
413 }
414
415 friend inline bool operator!=(const capture_allocator&, const capture_allocator&) {
416 return false;
417 }
418};
419
420template <typename T>
422public:
423 typedef std::size_t size_type;
424 typedef std::ptrdiff_t difference_type;
425 typedef T* pointer;
426 typedef const T* const_pointer;
427 typedef T& reference;
428 typedef const T& const_reference;
429 typedef T value_type;
430 template <typename U>
431 struct rebind {
433 };
434
436 template <typename U>
437 capture_allocator(const capture_allocator<U>& x) : new_delete_m(x.new_delete()) {}
438
442 capture_allocator& operator=(capture_allocator&&) noexcept = default;
443
444 pointer address(reference x) const { return &x; }
445 const_pointer address(const_reference x) const { return &x; }
447 if (n > max_size())
448 throw std::bad_alloc();
449 pointer result = static_cast<pointer>(new_delete_m->new_(n * sizeof(T)));
450 if (!result)
451 throw std::bad_alloc();
452 return result;
453 }
454 void deallocate(pointer p, size_type) { new_delete_m->delete_(p); }
455 size_type max_size() const { return size_type(-1) / sizeof(T); }
456 void construct(pointer p, const T& x) { adobe::construct(p, x); }
458
459 friend inline bool operator==(const capture_allocator& x, const capture_allocator& y) {
460 return x.new_delete_m == y.new_delete_m;
461 }
462
463 friend inline bool operator!=(const capture_allocator& x, const capture_allocator& y) {
464 return x.new_delete_m != y.new_delete_m;
465 }
466
467 const new_delete_t* new_delete() const { return new_delete_m; }
468
469private:
470 const new_delete_t* new_delete_m;
471};
472
474/**************************************************************************************************/
475
476} // namespace version_1
477
478/**************************************************************************************************/
479
480/*
481 Note (sparent) : The aligned storage class is intended to pad out an item of size_t such that
482 anything following it is aligned to the max alignement on the machine - in this case, quadword.
483
484 REVISIT (sparent) : This is a different beast than C++11 aligned storage. See if we can
485 replace usage with C++11 aligned storage.
486*/
487
491template <typename T>
493public:
495
496 explicit aligned_storage(T x) { construct_at(&get(), std::move(x)); }
497
499
501 aligned_storage(aligned_storage&& x) { construct_at(&get(), std::move(x.get())); }
502
504 swap(*this, x);
505 return *this;
506 }
507
508 T& get() { return *static_cast<T*>(storage()); }
509 const T& get() const { return *static_cast<const T*>(storage()); }
510
511 friend inline void swap(aligned_storage& x, aligned_storage& y) { swap(x.get(), y.get()); }
512
513private:
514 enum { word_size = 16 }; // quad word alignment
515
516 typedef double
517 storage_t[((sizeof(T) + (word_size - 1)) / word_size) * (word_size / sizeof(double))];
518
519 void* storage() { return &data_m; }
520 const void* storage() const { return &data_m; }
521 storage_t data_m;
522
523 static_assert(sizeof(T) <= sizeof(storage_t));
524};
525
527/**************************************************************************************************/
528
529} // namespace adobe
530
531/**************************************************************************************************/
532
533#endif
534
535/**************************************************************************************************/
The template class auto_resource< X, Traits > provides similar functionality to unique_ptr for resour...
Definition memory.hpp:202
traits_type::element_type element_type
Definition memory.hpp:208
void reset(pointer_type p=0)
Definition memory.hpp:321
pointer_type get() const
Definition memory.hpp:308
bool operator!() const
Definition memory.hpp:331
pointer_type release()
Definition memory.hpp:314
traits_type::pointer_type pointer_type
Definition memory.hpp:209
auto_resource(pointer_type p=0)
Definition memory.hpp:266
auto_resource & operator=(auto_resource &)
Definition memory.hpp:279
friend bool operator!=(const capture_allocator &, const capture_allocator &)
Definition memory.hpp:415
friend bool operator==(const capture_allocator &, const capture_allocator &)
Definition memory.hpp:411
capture_allocator(const capture_allocator &)=default
capture_allocator(const capture_allocator< U > &x)
Definition memory.hpp:437
void deallocate(pointer p, size_type)
Definition memory.hpp:454
friend bool operator!=(const capture_allocator &x, const capture_allocator &y)
Definition memory.hpp:463
pointer address(reference x) const
Definition memory.hpp:444
void construct(pointer p, const T &x)
Definition memory.hpp:456
const_pointer address(const_reference x) const
Definition memory.hpp:445
capture_allocator & operator=(const capture_allocator &)=default
const new_delete_t * new_delete() const
Definition memory.hpp:467
friend bool operator==(const capture_allocator &x, const capture_allocator &y)
Definition memory.hpp:459
pointer allocate(size_type n, capture_allocator< void >::const_pointer=0)
Definition memory.hpp:446
capture_allocator(capture_allocator &&) noexcept=default
const new_delete_t local_new_delete_g
void destroy(T *p)
Definition memory.hpp:338
constexpr auto construct(T *p, U &&x)
Definition memory.hpp:352
F uninitialized_move(I f, I l, F r)
Similar to std::uninitialized_copy but with move semantics.
Definition memory.hpp:377
T * construct_at(T *p, Args &&... args)
Definition memory.hpp:347
aligned_storage & operator=(aligned_storage x)
Definition memory.hpp:503
aligned_storage(const aligned_storage &x)
Definition memory.hpp:500
friend void swap(aligned_storage &x, aligned_storage &y)
Definition memory.hpp:511
const T & get() const
Definition memory.hpp:509
aligned_storage(aligned_storage &&x)
Definition memory.hpp:501
void operator()(const T *x) const
Definition memory.hpp:56
void operator()(const T *x) const
Definition memory.hpp:61
bool operator()(const T *x) const
Definition memory.hpp:36
bool operator()(const T *x) const
Definition memory.hpp:42
adobe::ptr_traits< U > other
Definition memory.hpp:161
static void delete_ptr(pointer_type x)
Definition memory.hpp:165
static bool empty_ptr(const_pointer_type x)
Definition memory.hpp:166
const pointer_type const_pointer_type
Definition memory.hpp:157
adobe::ptr_traits< U > other
Definition memory.hpp:83
static void delete_ptr(pointer_type x)
Definition memory.hpp:87
static bool empty_ptr(const_pointer_type x)
Definition memory.hpp:88