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