extptr_allocator.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // <extptr_allocator.h> -*- C++ -*-
  2. // Copyright (C) 2008-2023 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 <bits/requires_hosted.h> // GNU extensions are currently omitted
  33. #include <memory>
  34. #include <ext/numeric_traits.h>
  35. #include <ext/pointer.h>
  36. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39. /**
  40. * @brief An example allocator which uses a non-standard pointer type.
  41. * @ingroup allocators
  42. *
  43. * This allocator specifies that containers use a 'relative pointer' as it's
  44. * pointer type. (See ext/pointer.h) Memory allocation in this example
  45. * is still performed using std::allocator.
  46. */
  47. template<typename _Tp>
  48. class _ExtPtr_allocator
  49. {
  50. public:
  51. typedef std::size_t size_type;
  52. typedef std::ptrdiff_t difference_type;
  53. // Note the non-standard pointer types.
  54. typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer;
  55. typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> >
  56. const_pointer;
  57. typedef _Tp& reference;
  58. typedef const _Tp& const_reference;
  59. typedef _Tp value_type;
  60. template<typename _Up>
  61. struct rebind
  62. { typedef _ExtPtr_allocator<_Up> other; };
  63. _ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
  64. : _M_real_alloc() { }
  65. _ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT
  66. : _M_real_alloc(__rarg._M_real_alloc) { }
  67. template<typename _Up>
  68. _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg)
  69. _GLIBCXX_USE_NOEXCEPT
  70. : _M_real_alloc(__rarg._M_getUnderlyingImp()) { }
  71. ~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT
  72. { }
  73. pointer address(reference __x) const _GLIBCXX_NOEXCEPT
  74. { return std::__addressof(__x); }
  75. const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT
  76. { return std::__addressof(__x); }
  77. _GLIBCXX_NODISCARD pointer allocate(size_type __n, const void* = 0)
  78. { return _M_real_alloc.allocate(__n); }
  79. void deallocate(pointer __p, size_type __n)
  80. { _M_real_alloc.deallocate(__p.get(), __n); }
  81. size_type max_size() const _GLIBCXX_USE_NOEXCEPT
  82. { return __numeric_traits<size_type>::__max / sizeof(_Tp); }
  83. #if __cplusplus >= 201103L
  84. template<typename _Up, typename... _Args>
  85. void
  86. construct(_Up* __p, _Args&&... __args)
  87. { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  88. template<typename... _Args>
  89. void
  90. construct(pointer __p, _Args&&... __args)
  91. { construct(__p.get(), std::forward<_Args>(__args)...); }
  92. template<typename _Up>
  93. void
  94. destroy(_Up* __p)
  95. { __p->~_Up(); }
  96. void destroy(pointer __p)
  97. { destroy(__p.get()); }
  98. #else
  99. void construct(pointer __p, const _Tp& __val)
  100. { ::new(__p.get()) _Tp(__val); }
  101. void destroy(pointer __p)
  102. { __p->~_Tp(); }
  103. #endif
  104. template<typename _Up>
  105. inline bool
  106. operator==(const _ExtPtr_allocator<_Up>& __rarg) const
  107. { return _M_real_alloc == __rarg._M_getUnderlyingImp(); }
  108. inline bool
  109. operator==(const _ExtPtr_allocator& __rarg) const
  110. { return _M_real_alloc == __rarg._M_real_alloc; }
  111. #if __cpp_impl_three_way_comparison < 201907L
  112. template<typename _Up>
  113. inline bool
  114. operator!=(const _ExtPtr_allocator<_Up>& __rarg) const
  115. { return _M_real_alloc != __rarg._M_getUnderlyingImp(); }
  116. inline bool
  117. operator!=(const _ExtPtr_allocator& __rarg) const
  118. { return _M_real_alloc != __rarg._M_real_alloc; }
  119. #endif
  120. template<typename _Up>
  121. inline friend void
  122. swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&);
  123. // A method specific to this implementation.
  124. const std::allocator<_Tp>&
  125. _M_getUnderlyingImp() const
  126. { return _M_real_alloc; }
  127. private:
  128. std::allocator<_Tp> _M_real_alloc;
  129. };
  130. // _ExtPtr_allocator<void> specialization.
  131. template<>
  132. class _ExtPtr_allocator<void>
  133. {
  134. public:
  135. typedef std::size_t size_type;
  136. typedef std::ptrdiff_t difference_type;
  137. typedef void value_type;
  138. // Note the non-standard pointer types
  139. typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer;
  140. typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
  141. const_pointer;
  142. _ExtPtr_allocator() { }
  143. template<typename _Up>
  144. _ExtPtr_allocator(const _ExtPtr_allocator<_Up>&) { }
  145. template<typename _Up>
  146. struct rebind
  147. { typedef _ExtPtr_allocator<_Up> other; };
  148. private:
  149. std::allocator<void> _M_real_alloc;
  150. };
  151. template<typename _Tp>
  152. inline void
  153. swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg)
  154. {
  155. std::allocator<_Tp> __tmp( __rarg._M_real_alloc );
  156. __rarg._M_real_alloc = __larg._M_real_alloc;
  157. __larg._M_real_alloc = __tmp;
  158. }
  159. _GLIBCXX_END_NAMESPACE_VERSION
  160. } // namespace
  161. #endif /* _EXTPTR_ALLOCATOR_H */