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.

257 lines
8.3KB

  1. // nonstandard construct and destroy functions -*- 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. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 1996,1997
  35. * Silicon Graphics Computer Systems, Inc.
  36. *
  37. * Permission to use, copy, modify, distribute and sell this software
  38. * and its documentation for any purpose is hereby granted without fee,
  39. * provided that the above copyright notice appear in all copies and
  40. * that both that copyright notice and this permission notice appear
  41. * in supporting documentation. Silicon Graphics makes no
  42. * representations about the suitability of this software for any
  43. * purpose. It is provided "as is" without express or implied warranty.
  44. */
  45. /** @file bits/stl_construct.h
  46. * This is an internal header file, included by other library headers.
  47. * Do not attempt to use it directly. @headername{memory}
  48. */
  49. #ifndef _STL_CONSTRUCT_H
  50. #define _STL_CONSTRUCT_H 1
  51. #include <new>
  52. #include <bits/move.h>
  53. #include <bits/stl_iterator_base_types.h> // for iterator_traits
  54. #include <bits/stl_iterator_base_funcs.h> // for advance
  55. /* This file provides the C++17 functions std::destroy_at, std::destroy, and
  56. * std::destroy_n, and the C++20 function std::construct_at.
  57. * It also provides std::_Construct, std::_Destroy,and std::_Destroy_n functions
  58. * which are defined in all standard modes and so can be used in C++98-14 code.
  59. * The _Destroy functions will dispatch to destroy_at during constant
  60. * evaluation, because calls to that function are intercepted by the compiler
  61. * to allow use in constant expressions.
  62. */
  63. namespace std _GLIBCXX_VISIBILITY(default)
  64. {
  65. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  66. #if __cplusplus >= 201703L
  67. template <typename _Tp>
  68. _GLIBCXX20_CONSTEXPR inline void
  69. destroy_at(_Tp* __location)
  70. {
  71. if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
  72. {
  73. for (auto& __x : *__location)
  74. std::destroy_at(std::__addressof(__x));
  75. }
  76. else
  77. __location->~_Tp();
  78. }
  79. #if __cplusplus > 201703L
  80. template<typename _Tp, typename... _Args>
  81. constexpr auto
  82. construct_at(_Tp* __location, _Args&&... __args)
  83. noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
  84. -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
  85. { return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
  86. #endif // C++20
  87. #endif// C++17
  88. /**
  89. * Constructs an object in existing memory by invoking an allocated
  90. * object's constructor with an initializer.
  91. */
  92. #if __cplusplus >= 201103L
  93. template<typename _Tp, typename... _Args>
  94. inline void
  95. _Construct(_Tp* __p, _Args&&... __args)
  96. { ::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...); }
  97. #else
  98. template<typename _T1, typename _T2>
  99. inline void
  100. _Construct(_T1* __p, const _T2& __value)
  101. {
  102. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  103. // 402. wrong new expression in [some_]allocator::construct
  104. ::new(static_cast<void*>(__p)) _T1(__value);
  105. }
  106. #endif
  107. template<typename _T1>
  108. inline void
  109. _Construct_novalue(_T1* __p)
  110. { ::new(static_cast<void*>(__p)) _T1; }
  111. template<typename _ForwardIterator>
  112. _GLIBCXX20_CONSTEXPR void
  113. _Destroy(_ForwardIterator __first, _ForwardIterator __last);
  114. /**
  115. * Destroy the object pointed to by a pointer type.
  116. */
  117. template<typename _Tp>
  118. _GLIBCXX14_CONSTEXPR inline void
  119. _Destroy(_Tp* __pointer)
  120. {
  121. #if __cplusplus > 201703L
  122. std::destroy_at(__pointer);
  123. #else
  124. __pointer->~_Tp();
  125. #endif
  126. }
  127. template<bool>
  128. struct _Destroy_aux
  129. {
  130. template<typename _ForwardIterator>
  131. static _GLIBCXX20_CONSTEXPR void
  132. __destroy(_ForwardIterator __first, _ForwardIterator __last)
  133. {
  134. for (; __first != __last; ++__first)
  135. std::_Destroy(std::__addressof(*__first));
  136. }
  137. };
  138. template<>
  139. struct _Destroy_aux<true>
  140. {
  141. template<typename _ForwardIterator>
  142. static void
  143. __destroy(_ForwardIterator, _ForwardIterator) { }
  144. };
  145. /**
  146. * Destroy a range of objects. If the value_type of the object has
  147. * a trivial destructor, the compiler should optimize all of this
  148. * away, otherwise the objects' destructors must be invoked.
  149. */
  150. template<typename _ForwardIterator>
  151. _GLIBCXX20_CONSTEXPR inline void
  152. _Destroy(_ForwardIterator __first, _ForwardIterator __last)
  153. {
  154. typedef typename iterator_traits<_ForwardIterator>::value_type
  155. _Value_type;
  156. #if __cplusplus >= 201103L
  157. // A deleted destructor is trivial, this ensures we reject such types:
  158. static_assert(is_destructible<_Value_type>::value,
  159. "value type is destructible");
  160. #endif
  161. #if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
  162. if (std::is_constant_evaluated())
  163. return _Destroy_aux<false>::__destroy(__first, __last);
  164. #endif
  165. std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
  166. __destroy(__first, __last);
  167. }
  168. template<bool>
  169. struct _Destroy_n_aux
  170. {
  171. template<typename _ForwardIterator, typename _Size>
  172. static _GLIBCXX20_CONSTEXPR _ForwardIterator
  173. __destroy_n(_ForwardIterator __first, _Size __count)
  174. {
  175. for (; __count > 0; (void)++__first, --__count)
  176. std::_Destroy(std::__addressof(*__first));
  177. return __first;
  178. }
  179. };
  180. template<>
  181. struct _Destroy_n_aux<true>
  182. {
  183. template<typename _ForwardIterator, typename _Size>
  184. static _ForwardIterator
  185. __destroy_n(_ForwardIterator __first, _Size __count)
  186. {
  187. std::advance(__first, __count);
  188. return __first;
  189. }
  190. };
  191. /**
  192. * Destroy a range of objects. If the value_type of the object has
  193. * a trivial destructor, the compiler should optimize all of this
  194. * away, otherwise the objects' destructors must be invoked.
  195. */
  196. template<typename _ForwardIterator, typename _Size>
  197. _GLIBCXX20_CONSTEXPR inline _ForwardIterator
  198. _Destroy_n(_ForwardIterator __first, _Size __count)
  199. {
  200. typedef typename iterator_traits<_ForwardIterator>::value_type
  201. _Value_type;
  202. #if __cplusplus >= 201103L
  203. // A deleted destructor is trivial, this ensures we reject such types:
  204. static_assert(is_destructible<_Value_type>::value,
  205. "value type is destructible");
  206. #endif
  207. #if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
  208. if (std::is_constant_evaluated())
  209. return _Destroy_n_aux<false>::__destroy_n(__first, __count);
  210. #endif
  211. return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
  212. __destroy_n(__first, __count);
  213. }
  214. #if __cplusplus >= 201703L
  215. template <typename _ForwardIterator>
  216. _GLIBCXX20_CONSTEXPR inline void
  217. destroy(_ForwardIterator __first, _ForwardIterator __last)
  218. {
  219. std::_Destroy(__first, __last);
  220. }
  221. template <typename _ForwardIterator, typename _Size>
  222. _GLIBCXX20_CONSTEXPR inline _ForwardIterator
  223. destroy_n(_ForwardIterator __first, _Size __count)
  224. {
  225. return std::_Destroy_n(__first, __count);
  226. }
  227. #endif // C++17
  228. _GLIBCXX_END_NAMESPACE_VERSION
  229. } // namespace std
  230. #endif /* _STL_CONSTRUCT_H */