memory 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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. * @ingroup memory
  168. */
  169. template<size_t _Align, class _Tp>
  170. [[nodiscard,__gnu__::__always_inline__]]
  171. constexpr _Tp* assume_aligned(_Tp* __ptr)
  172. {
  173. static_assert(std::has_single_bit(_Align));
  174. _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
  175. return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
  176. }
  177. #endif // C++2a
  178. #if __cplusplus > 201703L
  179. template<typename _Tp>
  180. struct __is_pair : false_type { };
  181. template<typename _Tp, typename _Up>
  182. struct __is_pair<pair<_Tp, _Up>> : true_type { };
  183. template<typename _Tp, typename _Up>
  184. struct __is_pair<const pair<_Tp, _Up>> : true_type { };
  185. /** @addtogroup allocators
  186. * @{
  187. */
  188. template<typename _Tp, typename __ = _Require<__not_<__is_pair<_Tp>>>,
  189. typename _Alloc, typename... _Args>
  190. constexpr auto
  191. __uses_alloc_args(const _Alloc& __a, _Args&&... __args) noexcept
  192. {
  193. if constexpr (uses_allocator_v<remove_cv_t<_Tp>, _Alloc>)
  194. {
  195. if constexpr (is_constructible_v<_Tp, allocator_arg_t,
  196. const _Alloc&, _Args...>)
  197. {
  198. return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(
  199. allocator_arg, __a, std::forward<_Args>(__args)...);
  200. }
  201. else
  202. {
  203. static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
  204. "construction with an allocator must be possible"
  205. " if uses_allocator is true");
  206. return tuple<_Args&&..., const _Alloc&>(
  207. std::forward<_Args>(__args)..., __a);
  208. }
  209. }
  210. else
  211. {
  212. static_assert(is_constructible_v<_Tp, _Args...>);
  213. return tuple<_Args&&...>(std::forward<_Args>(__args)...);
  214. }
  215. }
  216. #if __cpp_concepts
  217. template<typename _Tp>
  218. concept _Std_pair = __is_pair<_Tp>::value;
  219. #endif
  220. // This is a temporary workaround until -fconcepts is implied by -std=gnu++2a
  221. #if __cpp_concepts
  222. # define _GLIBCXX_STD_PAIR_CONSTRAINT(T) _Std_pair T
  223. # define _GLIBCXX_STD_PAIR_CONSTRAINT_(T) _Std_pair T
  224. #else
  225. # define _GLIBCXX_STD_PAIR_CONSTRAINT(T) \
  226. typename T, typename __ = _Require<__is_pair<T>>
  227. # define _GLIBCXX_STD_PAIR_CONSTRAINT_(T) typename T, typename
  228. #endif
  229. template<typename _Tp,
  230. #if ! __cpp_concepts
  231. typename __ = _Require<__not_<__is_pair<_Tp>>>,
  232. #endif
  233. typename _Alloc, typename... _Args>
  234. constexpr auto
  235. uses_allocator_construction_args(const _Alloc& __a,
  236. _Args&&... __args) noexcept
  237. #if __cpp_concepts
  238. requires (! _Std_pair<_Tp>)
  239. #endif
  240. {
  241. return std::__uses_alloc_args<_Tp>(__a, std::forward<_Args>(__args)...);
  242. }
  243. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  244. typename _Tuple1, typename _Tuple2>
  245. constexpr auto
  246. uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
  247. _Tuple1&& __x, _Tuple2&& __y) noexcept;
  248. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc>
  249. constexpr auto
  250. uses_allocator_construction_args(const _Alloc&) noexcept;
  251. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  252. typename _Up, typename _Vp>
  253. constexpr auto
  254. uses_allocator_construction_args(const _Alloc&, _Up&&, _Vp&&) noexcept;
  255. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  256. typename _Up, typename _Vp>
  257. constexpr auto
  258. uses_allocator_construction_args(const _Alloc&,
  259. const pair<_Up, _Vp>&) noexcept;
  260. template<_GLIBCXX_STD_PAIR_CONSTRAINT(_Tp), typename _Alloc,
  261. typename _Up, typename _Vp>
  262. constexpr auto
  263. uses_allocator_construction_args(const _Alloc&, pair<_Up, _Vp>&&) noexcept;
  264. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  265. typename _Tuple1, typename _Tuple2>
  266. constexpr auto
  267. uses_allocator_construction_args(const _Alloc& __a, piecewise_construct_t,
  268. _Tuple1&& __x, _Tuple2&& __y) noexcept
  269. {
  270. using _Tp1 = typename _Tp::first_type;
  271. using _Tp2 = typename _Tp::second_type;
  272. return std::make_tuple(piecewise_construct,
  273. std::apply([&__a](auto&&... __args1) {
  274. return std::uses_allocator_construction_args<_Tp1>(
  275. __a, std::forward<decltype(__args1)>(__args1)...);
  276. }, std::forward<_Tuple1>(__x)),
  277. std::apply([&__a](auto&&... __args2) {
  278. return std::uses_allocator_construction_args<_Tp2>(
  279. __a, std::forward<decltype(__args2)>(__args2)...);
  280. }, std::forward<_Tuple2>(__y)));
  281. }
  282. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc>
  283. constexpr auto
  284. uses_allocator_construction_args(const _Alloc& __a) noexcept
  285. {
  286. using _Tp1 = typename _Tp::first_type;
  287. using _Tp2 = typename _Tp::second_type;
  288. return std::make_tuple(piecewise_construct,
  289. std::uses_allocator_construction_args<_Tp1>(__a),
  290. std::uses_allocator_construction_args<_Tp2>(__a));
  291. }
  292. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  293. typename _Up, typename _Vp>
  294. constexpr auto
  295. uses_allocator_construction_args(const _Alloc& __a, _Up&& __u, _Vp&& __v)
  296. noexcept
  297. {
  298. using _Tp1 = typename _Tp::first_type;
  299. using _Tp2 = typename _Tp::second_type;
  300. return std::make_tuple(piecewise_construct,
  301. std::uses_allocator_construction_args<_Tp1>(__a,
  302. std::forward<_Up>(__u)),
  303. std::uses_allocator_construction_args<_Tp2>(__a,
  304. std::forward<_Vp>(__v)));
  305. }
  306. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  307. typename _Up, typename _Vp>
  308. constexpr auto
  309. uses_allocator_construction_args(const _Alloc& __a,
  310. const pair<_Up, _Vp>& __pr) noexcept
  311. {
  312. using _Tp1 = typename _Tp::first_type;
  313. using _Tp2 = typename _Tp::second_type;
  314. return std::make_tuple(piecewise_construct,
  315. std::uses_allocator_construction_args<_Tp1>(__a, __pr.first),
  316. std::uses_allocator_construction_args<_Tp2>(__a, __pr.second));
  317. }
  318. template<_GLIBCXX_STD_PAIR_CONSTRAINT_(_Tp), typename _Alloc,
  319. typename _Up, typename _Vp>
  320. constexpr auto
  321. uses_allocator_construction_args(const _Alloc& __a,
  322. pair<_Up, _Vp>&& __pr) noexcept
  323. {
  324. using _Tp1 = typename _Tp::first_type;
  325. using _Tp2 = typename _Tp::second_type;
  326. return std::make_tuple(piecewise_construct,
  327. std::uses_allocator_construction_args<_Tp1>(__a,
  328. std::move(__pr).first),
  329. std::uses_allocator_construction_args<_Tp2>(__a,
  330. std::move(__pr).second));
  331. }
  332. template<typename _Tp, typename _Alloc, typename... _Args>
  333. inline _Tp
  334. make_obj_using_allocator(const _Alloc& __a, _Args&&... __args)
  335. {
  336. return std::make_from_tuple<_Tp>(
  337. std::uses_allocator_construction_args<_Tp>(__a,
  338. std::forward<_Args>(__args)...));
  339. }
  340. template<typename _Tp, typename _Alloc, typename... _Args>
  341. inline _Tp*
  342. uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a,
  343. _Args&&... __args)
  344. {
  345. return std::apply([&](auto&&... __xs) {
  346. return std::construct_at(__p, std::forward<decltype(__xs)>(__xs)...);
  347. }, std::uses_allocator_construction_args<_Tp>(__a,
  348. std::forward<_Args>(__args)...));
  349. }
  350. // @}
  351. #endif // C++2a
  352. _GLIBCXX_END_NAMESPACE_VERSION
  353. } // namespace
  354. #endif // C++11
  355. #if __cplusplus > 201402L
  356. // Parallel STL algorithms
  357. # if _PSTL_EXECUTION_POLICIES_DEFINED
  358. // If <execution> has already been included, pull in implementations
  359. # include <pstl/glue_memory_impl.h>
  360. # else
  361. // Otherwise just pull in forward declarations
  362. # include <pstl/glue_memory_defs.h>
  363. # endif
  364. // Feature test macro for parallel algorithms
  365. # define __cpp_lib_parallel_algorithm 201603L
  366. #endif // C++17
  367. #endif /* _GLIBCXX_MEMORY */