You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
8.8KB

  1. // Allocators -*- C++ -*-
  2. // Copyright (C) 2001-2020 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. * Copyright (c) 1996-1997
  22. * Silicon Graphics Computer Systems, Inc.
  23. *
  24. * Permission to use, copy, modify, distribute and sell this software
  25. * and its documentation for any purpose is hereby granted without fee,
  26. * provided that the above copyright notice appear in all copies and
  27. * that both that copyright notice and this permission notice appear
  28. * in supporting documentation. Silicon Graphics makes no
  29. * representations about the suitability of this software for any
  30. * purpose. It is provided "as is" without express or implied warranty.
  31. */
  32. /** @file bits/allocator.h
  33. * This is an internal header file, included by other library headers.
  34. * Do not attempt to use it directly. @headername{memory}
  35. */
  36. #ifndef _ALLOCATOR_H
  37. #define _ALLOCATOR_H 1
  38. #include <bits/c++allocator.h> // Define the base class to std::allocator.
  39. #include <bits/memoryfwd.h>
  40. #if __cplusplus >= 201103L
  41. #include <type_traits>
  42. #endif
  43. #define __cpp_lib_incomplete_container_elements 201505
  44. namespace std _GLIBCXX_VISIBILITY(default)
  45. {
  46. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  47. /**
  48. * @addtogroup allocators
  49. * @{
  50. */
  51. /// allocator<void> specialization.
  52. template<>
  53. class allocator<void>
  54. {
  55. public:
  56. typedef void value_type;
  57. typedef size_t size_type;
  58. typedef ptrdiff_t difference_type;
  59. #if __cplusplus <= 201703L
  60. typedef void* pointer;
  61. typedef const void* const_pointer;
  62. template<typename _Tp1>
  63. struct rebind
  64. { typedef allocator<_Tp1> other; };
  65. #else
  66. allocator() = default;
  67. template<typename _Up>
  68. constexpr
  69. allocator(const allocator<_Up>&) { }
  70. #endif // ! C++20
  71. #if __cplusplus >= 201103L && __cplusplus <= 201703L
  72. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  73. // 2103. std::allocator propagate_on_container_move_assignment
  74. typedef true_type propagate_on_container_move_assignment;
  75. typedef true_type is_always_equal;
  76. template<typename _Up, typename... _Args>
  77. void
  78. construct(_Up* __p, _Args&&... __args)
  79. noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
  80. { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  81. template<typename _Up>
  82. void
  83. destroy(_Up* __p)
  84. noexcept(std::is_nothrow_destructible<_Up>::value)
  85. { __p->~_Up(); }
  86. #endif // C++11 to C++17
  87. };
  88. /**
  89. * @brief The @a standard allocator, as per [20.4].
  90. *
  91. * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator
  92. * for further details.
  93. *
  94. * @tparam _Tp Type of allocated object.
  95. */
  96. template<typename _Tp>
  97. class allocator : public __allocator_base<_Tp>
  98. {
  99. public:
  100. typedef _Tp value_type;
  101. typedef size_t size_type;
  102. typedef ptrdiff_t difference_type;
  103. #if __cplusplus <= 201703L
  104. typedef _Tp* pointer;
  105. typedef const _Tp* const_pointer;
  106. typedef _Tp& reference;
  107. typedef const _Tp& const_reference;
  108. template<typename _Tp1>
  109. struct rebind
  110. { typedef allocator<_Tp1> other; };
  111. #endif
  112. #if __cplusplus >= 201103L
  113. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  114. // 2103. std::allocator propagate_on_container_move_assignment
  115. typedef true_type propagate_on_container_move_assignment;
  116. typedef true_type is_always_equal;
  117. #endif
  118. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  119. // 3035. std::allocator's constructors should be constexpr
  120. _GLIBCXX20_CONSTEXPR
  121. allocator() _GLIBCXX_NOTHROW { }
  122. _GLIBCXX20_CONSTEXPR
  123. allocator(const allocator& __a) _GLIBCXX_NOTHROW
  124. : __allocator_base<_Tp>(__a) { }
  125. #if __cplusplus >= 201103L
  126. // Avoid implicit deprecation.
  127. allocator& operator=(const allocator&) = default;
  128. #endif
  129. template<typename _Tp1>
  130. _GLIBCXX20_CONSTEXPR
  131. allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
  132. #if __cpp_constexpr_dynamic_alloc
  133. constexpr
  134. #endif
  135. ~allocator() _GLIBCXX_NOTHROW { }
  136. #if __cplusplus > 201703L
  137. [[nodiscard,__gnu__::__always_inline__]]
  138. constexpr _Tp*
  139. allocate(size_t __n)
  140. {
  141. #ifdef __cpp_lib_is_constant_evaluated
  142. if (std::is_constant_evaluated())
  143. return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
  144. #endif
  145. return __allocator_base<_Tp>::allocate(__n, 0);
  146. }
  147. [[__gnu__::__always_inline__]]
  148. constexpr void
  149. deallocate(_Tp* __p, size_t __n)
  150. {
  151. #ifdef __cpp_lib_is_constant_evaluated
  152. if (std::is_constant_evaluated())
  153. {
  154. ::operator delete(__p);
  155. return;
  156. }
  157. #endif
  158. __allocator_base<_Tp>::deallocate(__p, __n);
  159. }
  160. #endif // C++20
  161. friend _GLIBCXX20_CONSTEXPR bool
  162. operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
  163. { return true; }
  164. #if __cpp_impl_three_way_comparison < 201907L
  165. friend _GLIBCXX20_CONSTEXPR bool
  166. operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
  167. { return false; }
  168. #endif
  169. // Inherit everything else.
  170. };
  171. template<typename _T1, typename _T2>
  172. inline _GLIBCXX20_CONSTEXPR bool
  173. operator==(const allocator<_T1>&, const allocator<_T2>&)
  174. _GLIBCXX_NOTHROW
  175. { return true; }
  176. #if __cpp_impl_three_way_comparison < 201907L
  177. template<typename _T1, typename _T2>
  178. inline _GLIBCXX20_CONSTEXPR bool
  179. operator!=(const allocator<_T1>&, const allocator<_T2>&)
  180. _GLIBCXX_NOTHROW
  181. { return false; }
  182. #endif
  183. // Invalid allocator<cv T> partial specializations.
  184. // allocator_traits::rebind_alloc can be used to form a valid allocator type.
  185. template<typename _Tp>
  186. class allocator<const _Tp>
  187. {
  188. public:
  189. typedef _Tp value_type;
  190. template<typename _Up> allocator(const allocator<_Up>&) { }
  191. };
  192. template<typename _Tp>
  193. class allocator<volatile _Tp>
  194. {
  195. public:
  196. typedef _Tp value_type;
  197. template<typename _Up> allocator(const allocator<_Up>&) { }
  198. };
  199. template<typename _Tp>
  200. class allocator<const volatile _Tp>
  201. {
  202. public:
  203. typedef _Tp value_type;
  204. template<typename _Up> allocator(const allocator<_Up>&) { }
  205. };
  206. /// @} group allocator
  207. // Inhibit implicit instantiations for required instantiations,
  208. // which are defined via explicit instantiations elsewhere.
  209. #if _GLIBCXX_EXTERN_TEMPLATE
  210. extern template class allocator<char>;
  211. extern template class allocator<wchar_t>;
  212. #endif
  213. // Undefine.
  214. #undef __allocator_base
  215. // To implement Option 3 of DR 431.
  216. template<typename _Alloc, bool = __is_empty(_Alloc)>
  217. struct __alloc_swap
  218. { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
  219. template<typename _Alloc>
  220. struct __alloc_swap<_Alloc, false>
  221. {
  222. static void
  223. _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
  224. {
  225. // Precondition: swappable allocators.
  226. if (__one != __two)
  227. swap(__one, __two);
  228. }
  229. };
  230. // Optimize for stateless allocators.
  231. template<typename _Alloc, bool = __is_empty(_Alloc)>
  232. struct __alloc_neq
  233. {
  234. static bool
  235. _S_do_it(const _Alloc&, const _Alloc&)
  236. { return false; }
  237. };
  238. template<typename _Alloc>
  239. struct __alloc_neq<_Alloc, false>
  240. {
  241. static bool
  242. _S_do_it(const _Alloc& __one, const _Alloc& __two)
  243. { return __one != __two; }
  244. };
  245. #if __cplusplus >= 201103L
  246. template<typename _Tp, bool
  247. = __or_<is_copy_constructible<typename _Tp::value_type>,
  248. is_nothrow_move_constructible<typename _Tp::value_type>>::value>
  249. struct __shrink_to_fit_aux
  250. { static bool _S_do_it(_Tp&) noexcept { return false; } };
  251. template<typename _Tp>
  252. struct __shrink_to_fit_aux<_Tp, true>
  253. {
  254. static bool
  255. _S_do_it(_Tp& __c) noexcept
  256. {
  257. #if __cpp_exceptions
  258. try
  259. {
  260. _Tp(__make_move_if_noexcept_iterator(__c.begin()),
  261. __make_move_if_noexcept_iterator(__c.end()),
  262. __c.get_allocator()).swap(__c);
  263. return true;
  264. }
  265. catch(...)
  266. { return false; }
  267. #else
  268. return false;
  269. #endif
  270. }
  271. };
  272. #endif
  273. _GLIBCXX_END_NAMESPACE_VERSION
  274. } // namespace std
  275. #endif