extptr_allocator.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // <extptr_allocator.h> -*- C++ -*-
  2. // Copyright (C) 2008-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /**
  21. * @file ext/extptr_allocator.h
  22. * This file is a GNU extension to the Standard C++ Library.
  23. *
  24. * @author Bob Walters
  25. *
  26. * An example allocator which uses an alternative pointer type from
  27. * bits/pointer.h. Supports test cases which confirm container support
  28. * for alternative pointers.
  29. */
  30. #ifndef _EXTPTR_ALLOCATOR_H
  31. #define _EXTPTR_ALLOCATOR_H 1
  32. #include <memory>
  33. #include <ext/numeric_traits.h>
  34. #include <ext/pointer.h>
  35. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38. /**
  39. * @brief An example allocator which uses a non-standard pointer type.
  40. * @ingroup allocators
  41. *
  42. * This allocator specifies that containers use a 'relative pointer' as it's
  43. * pointer type. (See ext/pointer.h) Memory allocation in this example
  44. * is still performed using std::allocator.
  45. */
  46. template<typename _Tp>
  47. class _ExtPtr_allocator
  48. {
  49. public:
  50. typedef std::size_t size_type;
  51. typedef std::ptrdiff_t difference_type;
  52. // Note the non-standard pointer types.
  53. typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer;
  54. typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> >
  55. const_pointer;
  56. typedef _Tp& reference;
  57. typedef const _Tp& const_reference;
  58. typedef _Tp value_type;
  59. template<typename _Up>
  60. struct rebind
  61. { typedef _ExtPtr_allocator<_Up> other; };
  62. _ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
  63. : _M_real_alloc() { }
  64. _ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT
  65. : _M_real_alloc(__rarg._M_real_alloc) { }
  66. template<typename _Up>
  67. _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg)
  68. _GLIBCXX_USE_NOEXCEPT
  69. : _M_real_alloc(__rarg._M_getUnderlyingImp()) { }
  70. ~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
  71. { }
  72. pointer address(reference __x) const _GLIBCXX_NOEXCEPT
  73. { return std::__addressof(__x); }
  74. const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT
  75. { return std::__addressof(__x); }
  76. pointer allocate(size_type __n, void* __hint = 0)
  77. { return _M_real_alloc.allocate(__n,__hint); }
  78. void deallocate(pointer __p, size_type __n)
  79. { _M_real_alloc.deallocate(__p.get(), __n); }
  80. size_type max_size() const _GLIBCXX_USE_NOEXCEPT
  81. { return __numeric_traits<size_type>::__max / sizeof(_Tp); }
  82. #if __cplusplus >= 201103L
  83. template<typename _Up, typename... _Args>
  84. void
  85. construct(_Up* __p, _Args&&... __args)
  86. { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  87. template<typename... _Args>
  88. void
  89. construct(pointer __p, _Args&&... __args)
  90. { construct(__p.get(), std::forward<_Args>(__args)...); }
  91. template<typename _Up>
  92. void
  93. destroy(_Up* __p)
  94. { __p->~_Up(); }
  95. void destroy(pointer __p)
  96. { destroy(__p.get()); }
  97. #else
  98. void construct(pointer __p, const _Tp& __val)
  99. { ::new(__p.get()) _Tp(__val); }
  100. void destroy(pointer __p)
  101. { __p->~_Tp(); }
  102. #endif
  103. template<typename _Up>
  104. inline bool
  105. operator==(const _ExtPtr_allocator<_Up>& __rarg)
  106. { return _M_real_alloc == __rarg._M_getUnderlyingImp(); }
  107. inline bool
  108. operator==(const _ExtPtr_allocator& __rarg)
  109. { return _M_real_alloc == __rarg._M_real_alloc; }
  110. template<typename _Up>
  111. inline bool
  112. operator!=(const _ExtPtr_allocator<_Up>& __rarg)
  113. { return _M_real_alloc != __rarg._M_getUnderlyingImp(); }
  114. inline bool
  115. operator!=(const _ExtPtr_allocator& __rarg)
  116. { return _M_real_alloc != __rarg._M_real_alloc; }
  117. template<typename _Up>
  118. inline friend void
  119. swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&);
  120. // A method specific to this implementation.
  121. const std::allocator<_Tp>&
  122. _M_getUnderlyingImp() const
  123. { return _M_real_alloc; }
  124. private:
  125. std::allocator<_Tp> _M_real_alloc;
  126. };
  127. // _ExtPtr_allocator<void> specialization.
  128. template<>
  129. class _ExtPtr_allocator<void>
  130. {
  131. public:
  132. typedef std::size_t size_type;
  133. typedef std::ptrdiff_t difference_type;
  134. typedef void value_type;
  135. // Note the non-standard pointer types
  136. typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer;
  137. typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
  138. const_pointer;
  139. template<typename _Up>
  140. struct rebind
  141. { typedef _ExtPtr_allocator<_Up> other; };
  142. private:
  143. std::allocator<void> _M_real_alloc;
  144. };
  145. template<typename _Tp>
  146. inline void
  147. swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg)
  148. {
  149. std::allocator<_Tp> __tmp( __rarg._M_real_alloc );
  150. __rarg._M_real_alloc = __larg._M_real_alloc;
  151. __larg._M_real_alloc = __tmp;
  152. }
  153. _GLIBCXX_END_NAMESPACE_VERSION
  154. } // namespace
  155. #endif /* _EXTPTR_ALLOCATOR_H */