new_allocator.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Allocator that wraps operator new -*- C++ -*-
  2. // Copyright (C) 2001-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. /** @file bits/new_allocator.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{memory}
  23. */
  24. #ifndef _STD_NEW_ALLOCATOR_H
  25. #define _STD_NEW_ALLOCATOR_H 1
  26. #include <bits/c++config.h>
  27. #include <new>
  28. #include <bits/functexcept.h>
  29. #include <bits/move.h>
  30. #if __cplusplus >= 201103L
  31. #include <type_traits>
  32. #endif
  33. namespace std _GLIBCXX_VISIBILITY(default)
  34. {
  35. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  36. /**
  37. * @brief An allocator that uses global `new`, as per C++03 [20.4.1].
  38. * @ingroup allocators
  39. *
  40. * This is precisely the allocator defined in the C++ Standard.
  41. * - all allocation calls `operator new`
  42. * - all deallocation calls `operator delete`
  43. *
  44. * This is the default base-class implementation of `std::allocator`,
  45. * and is also the base-class of the `__gnu_cxx::new_allocator` extension.
  46. * You should use either `std::allocator` or `__gnu_cxx::new_allocator`
  47. * instead of using this directly.
  48. *
  49. * @tparam _Tp Type of allocated object.
  50. *
  51. * @headerfile memory
  52. */
  53. template<typename _Tp>
  54. class __new_allocator
  55. {
  56. public:
  57. typedef _Tp value_type;
  58. typedef std::size_t size_type;
  59. typedef std::ptrdiff_t difference_type;
  60. #if __cplusplus <= 201703L
  61. typedef _Tp* pointer;
  62. typedef const _Tp* const_pointer;
  63. typedef _Tp& reference;
  64. typedef const _Tp& const_reference;
  65. template<typename _Tp1>
  66. struct rebind
  67. { typedef __new_allocator<_Tp1> other; };
  68. #endif
  69. #if __cplusplus >= 201103L
  70. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  71. // 2103. propagate_on_container_move_assignment
  72. typedef std::true_type propagate_on_container_move_assignment;
  73. #endif
  74. __attribute__((__always_inline__))
  75. _GLIBCXX20_CONSTEXPR
  76. __new_allocator() _GLIBCXX_USE_NOEXCEPT { }
  77. __attribute__((__always_inline__))
  78. _GLIBCXX20_CONSTEXPR
  79. __new_allocator(const __new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
  80. template<typename _Tp1>
  81. __attribute__((__always_inline__))
  82. _GLIBCXX20_CONSTEXPR
  83. __new_allocator(const __new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
  84. #if __cplusplus >= 201103L
  85. __new_allocator& operator=(const __new_allocator&) = default;
  86. #endif
  87. #if __cplusplus <= 201703L
  88. ~__new_allocator() _GLIBCXX_USE_NOEXCEPT { }
  89. pointer
  90. address(reference __x) const _GLIBCXX_NOEXCEPT
  91. { return std::__addressof(__x); }
  92. const_pointer
  93. address(const_reference __x) const _GLIBCXX_NOEXCEPT
  94. { return std::__addressof(__x); }
  95. #endif
  96. #if __has_builtin(__builtin_operator_new) >= 201802L
  97. # define _GLIBCXX_OPERATOR_NEW __builtin_operator_new
  98. # define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete
  99. #else
  100. # define _GLIBCXX_OPERATOR_NEW ::operator new
  101. # define _GLIBCXX_OPERATOR_DELETE ::operator delete
  102. #endif
  103. // NB: __n is permitted to be 0. The C++ standard says nothing
  104. // about what the return value is when __n == 0.
  105. _GLIBCXX_NODISCARD _Tp*
  106. allocate(size_type __n, const void* = static_cast<const void*>(0))
  107. {
  108. #if __cplusplus >= 201103L
  109. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  110. // 3308. std::allocator<void>().allocate(n)
  111. static_assert(sizeof(_Tp) != 0, "cannot allocate incomplete types");
  112. #endif
  113. if (__builtin_expect(__n > this->_M_max_size(), false))
  114. {
  115. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  116. // 3190. allocator::allocate sometimes returns too little storage
  117. if (__n > (std::size_t(-1) / sizeof(_Tp)))
  118. std::__throw_bad_array_new_length();
  119. std::__throw_bad_alloc();
  120. }
  121. #if __cpp_aligned_new
  122. if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
  123. {
  124. std::align_val_t __al = std::align_val_t(alignof(_Tp));
  125. return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp),
  126. __al));
  127. }
  128. #endif
  129. return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
  130. }
  131. // __p is not permitted to be a null pointer.
  132. void
  133. deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__)))
  134. {
  135. #if __cpp_sized_deallocation
  136. # define _GLIBCXX_SIZED_DEALLOC(p, n) (p), (n) * sizeof(_Tp)
  137. #else
  138. # define _GLIBCXX_SIZED_DEALLOC(p, n) (p)
  139. #endif
  140. #if __cpp_aligned_new
  141. if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
  142. {
  143. _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n),
  144. std::align_val_t(alignof(_Tp)));
  145. return;
  146. }
  147. #endif
  148. _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n));
  149. }
  150. #undef _GLIBCXX_SIZED_DEALLOC
  151. #undef _GLIBCXX_OPERATOR_DELETE
  152. #undef _GLIBCXX_OPERATOR_NEW
  153. #if __cplusplus <= 201703L
  154. __attribute__((__always_inline__))
  155. size_type
  156. max_size() const _GLIBCXX_USE_NOEXCEPT
  157. { return _M_max_size(); }
  158. #if __cplusplus >= 201103L
  159. template<typename _Up, typename... _Args>
  160. __attribute__((__always_inline__))
  161. void
  162. construct(_Up* __p, _Args&&... __args)
  163. noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
  164. { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  165. template<typename _Up>
  166. __attribute__((__always_inline__))
  167. void
  168. destroy(_Up* __p)
  169. noexcept(std::is_nothrow_destructible<_Up>::value)
  170. { __p->~_Up(); }
  171. #else
  172. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  173. // 402. wrong new expression in [some_] allocator::construct
  174. __attribute__((__always_inline__))
  175. void
  176. construct(pointer __p, const _Tp& __val)
  177. { ::new((void *)__p) _Tp(__val); }
  178. __attribute__((__always_inline__))
  179. void
  180. destroy(pointer __p) { __p->~_Tp(); }
  181. #endif
  182. #endif // ! C++20
  183. template<typename _Up>
  184. friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR bool
  185. operator==(const __new_allocator&, const __new_allocator<_Up>&)
  186. _GLIBCXX_NOTHROW
  187. { return true; }
  188. #if __cpp_impl_three_way_comparison < 201907L
  189. template<typename _Up>
  190. friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR bool
  191. operator!=(const __new_allocator&, const __new_allocator<_Up>&)
  192. _GLIBCXX_NOTHROW
  193. { return false; }
  194. #endif
  195. private:
  196. __attribute__((__always_inline__))
  197. _GLIBCXX_CONSTEXPR size_type
  198. _M_max_size() const _GLIBCXX_USE_NOEXCEPT
  199. {
  200. #if __PTRDIFF_MAX__ < __SIZE_MAX__
  201. return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
  202. #else
  203. return std::size_t(-1) / sizeof(_Tp);
  204. #endif
  205. }
  206. };
  207. _GLIBCXX_END_NAMESPACE_VERSION
  208. } // namespace
  209. #endif