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.

430 lines
14KB

  1. // <memory> -*- 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) 1997-1999
  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. */
  33. /** @file include/memory
  34. * This is a Standard C++ Library header.
  35. * @ingroup memory
  36. */
  37. #ifndef _GLIBCXX_MEMORY
  38. #define _GLIBCXX_MEMORY 1
  39. #pragma GCC system_header
  40. /**
  41. * @defgroup memory Memory
  42. * @ingroup utilities
  43. *
  44. * Components for memory allocation, deallocation, and management.
  45. */
  46. /**
  47. * @defgroup pointer_abstractions Pointer Abstractions
  48. * @ingroup memory
  49. *
  50. * Smart pointers, etc.
  51. */
  52. #include <bits/stl_algobase.h>
  53. #include <bits/allocator.h>
  54. #include <bits/stl_construct.h>
  55. #include <bits/stl_uninitialized.h>
  56. #include <bits/stl_tempbuf.h>
  57. #include <bits/stl_raw_storage_iter.h>
  58. #include <bits/ranges_uninitialized.h>
  59. #if __cplusplus >= 201103L
  60. # include <exception> // std::exception
  61. # include <typeinfo> // std::type_info in get_deleter
  62. # include <iosfwd> // std::basic_ostream
  63. # include <ext/atomicity.h>
  64. # include <ext/concurrence.h>
  65. # include <bits/functexcept.h>
  66. # include <bits/stl_function.h> // std::less
  67. # include <bits/uses_allocator.h>
  68. # include <bits/alloc_traits.h>
  69. # include <type_traits>
  70. # include <debug/debug.h>
  71. # include <bits/unique_ptr.h>
  72. # include <bits/shared_ptr.h>
  73. # include <bits/shared_ptr_atomic.h>
  74. # if _GLIBCXX_USE_DEPRECATED
  75. # include <backward/auto_ptr.h>
  76. # endif
  77. #else
  78. # include <backward/auto_ptr.h>
  79. #endif
  80. #if __cplusplus >= 201103L
  81. #include <cstdint>
  82. #if __cplusplus > 201703L
  83. # include <bit> // for has_single_bit
  84. # include <new> // for placement operator new
  85. # include <tuple> // for tuple, make_tuple, make_from_tuple
  86. #endif
  87. namespace std _GLIBCXX_VISIBILITY(default)
  88. {
  89. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  90. /**
  91. * @brief Fit aligned storage in buffer.
  92. * @ingroup memory
  93. *
  94. * This function tries to fit @a __size bytes of storage with alignment
  95. * @a __align into the buffer @a __ptr of size @a __space bytes. If such
  96. * a buffer fits then @a __ptr is changed to point to the first byte of the
  97. * aligned storage and @a __space is reduced by the bytes used for alignment.
  98. *
  99. * C++11 20.6.5 [ptr.align]
  100. *
  101. * @param __align A fundamental or extended alignment value.
  102. * @param __size Size of the aligned storage required.
  103. * @param __ptr Pointer to a buffer of @a __space bytes.
  104. * @param __space Size of the buffer pointed to by @a __ptr.
  105. * @return the updated pointer if the aligned storage fits, otherwise nullptr.
  106. *
  107. */
  108. inline void*
  109. align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
  110. {
  111. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  112. const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
  113. #else
  114. // Cannot use std::uintptr_t so assume that std::size_t can be used instead.
  115. static_assert(sizeof(size_t) >= sizeof(void*),
  116. "std::size_t must be a suitable substitute for std::uintptr_t");
  117. const auto __intptr = reinterpret_cast<unsigned long long>(__ptr);
  118. #endif
  119. const auto __aligned = (__intptr - 1u + __align) & -__align;
  120. const auto __diff = __aligned - __intptr;
  121. if ((__size + __diff) > __space)
  122. return nullptr;
  123. else
  124. {
  125. __space -= __diff;
  126. return __ptr = reinterpret_cast<void*>(__aligned);
  127. }
  128. }
  129. /** @defgroup ptr_safety Pointer Safety and Garbage Collection
  130. * @ingroup memory
  131. *
  132. * Utilities to assist with garbage collection in an implementation
  133. * that supports <em>strict pointer safety</em>.
  134. * This implementation only supports <em>relaxed pointer safety</em>
  135. * and so these functions have no effect.
  136. *
  137. * C++11 20.6.4 [util.dynamic.safety], Pointer safety
  138. *
  139. * @{
  140. */
  141. /// Constants representing the different types of pointer safety.
  142. enum class pointer_safety { relaxed, preferred, strict };
  143. /// Inform a garbage collector that an object is still in use.
  144. inline void
  145. declare_reachable(void*) { }
  146. /// Unregister an object previously registered with declare_reachable.
  147. template <typename _Tp>
  148. inline _Tp*
  149. undeclare_reachable(_Tp* __p) { return __p; }
  150. /// Inform a garbage collector that a region of memory need not be traced.
  151. inline void
  152. declare_no_pointers(char*, size_t) { }
  153. /// Unregister a range previously registered with declare_no_pointers.
  154. inline void
  155. undeclare_no_pointers(char*, size_t) { }
  156. /// The type of pointer safety supported by the implementation.
  157. inline pointer_safety
  158. get_pointer_safety() noexcept { return pointer_safety::relaxed; }
  159. // @}
  160. #if __cplusplus > 201703L
  161. #define __cpp_lib_assume_aligned 201811L
  162. /** @brief Inform the compiler that a pointer is aligned.
  163. *
  164. * @tparam _Align An alignment value (i.e. a power of two)
  165. * @tparam _Tp An object type
  166. * @param __ptr A pointer that is aligned to _Align
  167. *
  168. * C++20 20.10.6 [ptr.align]
  169. *
  170. * @ingroup memory
  171. */
  172. template<size_t _Align, class _Tp>
  173. [[nodiscard,__gnu__::__always_inline__]]
  174. constexpr _Tp*
  175. assume_aligned(_Tp* __ptr) noexcept
  176. {
  177. static_assert(std::has_single_bit(_Align));
  178. if (std::is_constant_evaluated())
  179. return __ptr;
  180. else
  181. {
  182. // This function is expected to be used in hot code, where
  183. // __glibcxx_assert would add unwanted overhead.
  184. _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
  185. return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
  186. }
  187. }
  188. #endif // C++2a
  189. #if __cplusplus > 201703L
  190. template<typename _Tp>
  191. struct __is_pair : false_type { };
  192. template<typename _Tp, typename _Up>
  193. struct __is_pair<pair<_Tp, _Up>> : true_type { };
  194. template<typename _Tp, typename _Up>
  195. struct __is_pair<const pair<_Tp, _Up>> : true_type { };
  196. /** @addtogroup allocators
  197. * @{
  198. */
  199. template<typename _Tp, typename __ = _Require<__not_<__is_pair<_Tp>>>,
  200. typename _Alloc, typename... _Args>
  201. constexpr auto
  202. __uses_alloc_args(const _Alloc& __a, _Args&&... __args) noexcept
  203. {
  204. if constexpr (uses_allocator_v<remove_cv_t<_Tp>, _Alloc>)
  205. {
  206. if constexpr (is_constructible_v<_Tp, allocator_arg_t,
  207. const _Alloc&, _Args...>)
  208. {
  209. return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(
  210. allocator_arg, __a, std::forward<_Args>(__args)...);
  211. }
  212. else
  213. {
  214. static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
  215. "construction with an allocator must be possible"
  216. " if uses_allocator is true");
  217. return tuple<_Args&&..., const _Alloc&>(
  218. std::forward<_Args>(__args)..., __a);
  219. }
  220. }
  221. else
  222. {
  223. static_assert(is_constructible_v<_Tp, _Args...>);
  224. return tuple<_Args&&...>(std::forward<_Args>(__args)...);
  225. }
  226. }
  227. #if __cpp_concepts
  228. template<typename _Tp>
  229. concept _Std_pair = __is_pair<_Tp>::value;
  230. #endif
  231. // This is a temporary workaround until -fconcepts is implied by -std=gnu++2a
  232. #if __cpp_concepts
  233. # define _GLIBCXX_STD_PAIR_CONSTRAINT(T) _Std_pair T
  234. # define _GLIBCXX_STD_PAIR_CONSTRAINT_(T) _Std_pair T
  235. #else
  236. # define _GLIBCXX_STD_PAIR_CONSTRAINT(T) \
  237. typename T, typename __ = _Require<__is_pair<T>>
  238. # define _GLIBCXX_STD_PAIR_CONSTRAINT_(T) typename T, typename
  239. #endif
  240. template<typename _Tp,
  241. #if ! __cpp_concepts
  242. typename __ = _Require<__not_<__is_pair<_Tp>>>,
  243. #endif
  244. typename _Alloc, typename... _Args>
  245. constexpr auto
  246. uses_allocator_construction_args(const _Alloc& __a,
  247. _Args&&... __args) noexcept
  248. #if __cpp_concepts
  249. requires (! _Std_pair<_Tp>)
  250. #endif
  251. {
  252. return std::__uses_alloc_args<_Tp>(__a, std::forward<_Args>(__args)...);
  253. }
  254. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  255. typename _Tuple1, typename _Tuple2>
  256. constexpr auto
  257. uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
  258. _Tuple1&& __x, _Tuple2&& __y) noexcept;
  259. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc>
  260. constexpr auto
  261. uses_allocator_construction_args(const _Alloc&) noexcept;
  262. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  263. typename _Up, typename _Vp>
  264. constexpr auto
  265. uses_allocator_construction_args(const _Alloc&, _Up&&, _Vp&&) noexcept;
  266. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  267. typename _Up, typename _Vp>
  268. constexpr auto
  269. uses_allocator_construction_args(const _Alloc&,
  270. const pair<_Up, _Vp>&) noexcept;
  271. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  272. typename _Up, typename _Vp>
  273. constexpr auto
  274. uses_allocator_construction_args(const _Alloc&, pair<_Up, _Vp>&&) noexcept;
  275. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  276. typename _Tuple1, typename _Tuple2>
  277. constexpr auto
  278. uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
  279. _Tuple1&& __x, _Tuple2&& __y) noexcept
  280. {
  281. using _Tp1 = typename _Tp::first_type;
  282. using _Tp2 = typename _Tp::second_type;
  283. return std::make_tuple(piecewise_construct,
  284. std::apply([&__a](auto&&... __args1) {
  285. return std::uses_allocator_construction_args<_Tp1>(
  286. __a, std::forward<decltype(__args1)>(__args1)...);
  287. }, std::forward<_Tuple1>(__x)),
  288. std::apply([&__a](auto&&... __args2) {
  289. return std::uses_allocator_construction_args<_Tp2>(
  290. __a, std::forward<decltype(__args2)>(__args2)...);
  291. }, std::forward<_Tuple2>(__y)));
  292. }
  293. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc>
  294. constexpr auto
  295. uses_allocator_construction_args(const _Alloc& __a) noexcept
  296. {
  297. using _Tp1 = typename _Tp::first_type;
  298. using _Tp2 = typename _Tp::second_type;
  299. return std::make_tuple(piecewise_construct,
  300. std::uses_allocator_construction_args<_Tp1>(__a),
  301. std::uses_allocator_construction_args<_Tp2>(__a));
  302. }
  303. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  304. typename _Up, typename _Vp>
  305. constexpr auto
  306. uses_allocator_construction_args(const _Alloc& __a, _Up&& __u, _Vp&& __v)
  307. noexcept
  308. {
  309. using _Tp1 = typename _Tp::first_type;
  310. using _Tp2 = typename _Tp::second_type;
  311. return std::make_tuple(piecewise_construct,
  312. std::uses_allocator_construction_args<_Tp1>(__a,
  313. std::forward<_Up>(__u)),
  314. std::uses_allocator_construction_args<_Tp2>(__a,
  315. std::forward<_Vp>(__v)));
  316. }
  317. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  318. typename _Up, typename _Vp>
  319. constexpr auto
  320. uses_allocator_construction_args(const _Alloc& __a,
  321. const pair<_Up, _Vp>& __pr) noexcept
  322. {
  323. using _Tp1 = typename _Tp::first_type;
  324. using _Tp2 = typename _Tp::second_type;
  325. return std::make_tuple(piecewise_construct,
  326. std::uses_allocator_construction_args<_Tp1>(__a, __pr.first),
  327. std::uses_allocator_construction_args<_Tp2>(__a, __pr.second));
  328. }
  329. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  330. typename _Up, typename _Vp>
  331. constexpr auto
  332. uses_allocator_construction_args(const _Alloc& __a,
  333. pair<_Up, _Vp>&& __pr) noexcept
  334. {
  335. using _Tp1 = typename _Tp::first_type;
  336. using _Tp2 = typename _Tp::second_type;
  337. return std::make_tuple(piecewise_construct,
  338. std::uses_allocator_construction_args<_Tp1>(__a,
  339. std::move(__pr).first),
  340. std::uses_allocator_construction_args<_Tp2>(__a,
  341. std::move(__pr).second));
  342. }
  343. template<typename _Tp, typename _Alloc, typename... _Args>
  344. inline _Tp
  345. make_obj_using_allocator(const _Alloc& __a, _Args&&... __args)
  346. {
  347. return std::make_from_tuple<_Tp>(
  348. std::uses_allocator_construction_args<_Tp>(__a,
  349. std::forward<_Args>(__args)...));
  350. }
  351. template<typename _Tp, typename _Alloc, typename... _Args>
  352. inline _Tp*
  353. uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a,
  354. _Args&&... __args)
  355. {
  356. return std::apply([&](auto&&... __xs) {
  357. return std::construct_at(__p, std::forward<decltype(__xs)>(__xs)...);
  358. }, std::uses_allocator_construction_args<_Tp>(__a,
  359. std::forward<_Args>(__args)...));
  360. }
  361. // @}
  362. #endif // C++2a
  363. _GLIBCXX_END_NAMESPACE_VERSION
  364. } // namespace
  365. #endif // C++11
  366. #if __cplusplus > 201402L
  367. // Parallel STL algorithms
  368. # if _PSTL_EXECUTION_POLICIES_DEFINED
  369. // If <execution> has already been included, pull in implementations
  370. # include <pstl/glue_memory_impl.h>
  371. # else
  372. // Otherwise just pull in forward declarations
  373. # include <pstl/glue_memory_defs.h>
  374. # endif
  375. // Feature test macro for parallel algorithms
  376. # define __cpp_lib_parallel_algorithm 201603L
  377. #endif // C++17
  378. #endif /* _GLIBCXX_MEMORY */