Line data Source code
1 : // nonstandard construct and destroy functions -*- C++ -*-
2 :
3 : // Copyright (C) 2001-2022 Free Software Foundation, Inc.
4 : //
5 : // This file is part of the GNU ISO C++ Library. This library is free
6 : // software; you can redistribute it and/or modify it under the
7 : // terms of the GNU General Public License as published by the
8 : // Free Software Foundation; either version 3, or (at your option)
9 : // any later version.
10 :
11 : // This library is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 :
16 : // Under Section 7 of GPL version 3, you are granted additional
17 : // permissions described in the GCC Runtime Library Exception, version
18 : // 3.1, as published by the Free Software Foundation.
19 :
20 : // You should have received a copy of the GNU General Public License and
21 : // a copy of the GCC Runtime Library Exception along with this program;
22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 : // <http://www.gnu.org/licenses/>.
24 :
25 : /*
26 : *
27 : * Copyright (c) 1994
28 : * Hewlett-Packard Company
29 : *
30 : * Permission to use, copy, modify, distribute and sell this software
31 : * and its documentation for any purpose is hereby granted without fee,
32 : * provided that the above copyright notice appear in all copies and
33 : * that both that copyright notice and this permission notice appear
34 : * in supporting documentation. Hewlett-Packard Company makes no
35 : * representations about the suitability of this software for any
36 : * purpose. It is provided "as is" without express or implied warranty.
37 : *
38 : *
39 : * Copyright (c) 1996,1997
40 : * Silicon Graphics Computer Systems, Inc.
41 : *
42 : * Permission to use, copy, modify, distribute and sell this software
43 : * and its documentation for any purpose is hereby granted without fee,
44 : * provided that the above copyright notice appear in all copies and
45 : * that both that copyright notice and this permission notice appear
46 : * in supporting documentation. Silicon Graphics makes no
47 : * representations about the suitability of this software for any
48 : * purpose. It is provided "as is" without express or implied warranty.
49 : */
50 :
51 : /** @file bits/stl_construct.h
52 : * This is an internal header file, included by other library headers.
53 : * Do not attempt to use it directly. @headername{memory}
54 : */
55 :
56 : #ifndef _STL_CONSTRUCT_H
57 : #define _STL_CONSTRUCT_H 1
58 :
59 : #include <new>
60 : #include <bits/move.h>
61 : #include <bits/stl_iterator_base_types.h> // for iterator_traits
62 : #include <bits/stl_iterator_base_funcs.h> // for advance
63 :
64 : /* This file provides the C++17 functions std::destroy_at, std::destroy, and
65 : * std::destroy_n, and the C++20 function std::construct_at.
66 : * It also provides std::_Construct, std::_Destroy,and std::_Destroy_n functions
67 : * which are defined in all standard modes and so can be used in C++98-14 code.
68 : * The _Destroy functions will dispatch to destroy_at during constant
69 : * evaluation, because calls to that function are intercepted by the compiler
70 : * to allow use in constant expressions.
71 : */
72 :
73 : namespace std _GLIBCXX_VISIBILITY(default)
74 : {
75 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
76 :
77 : #if __cplusplus >= 201703L
78 : template <typename _Tp>
79 : _GLIBCXX20_CONSTEXPR inline void
80 : destroy_at(_Tp* __location)
81 : {
82 : if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
83 : {
84 : for (auto& __x : *__location)
85 : std::destroy_at(std::__addressof(__x));
86 : }
87 : else
88 : __location->~_Tp();
89 : }
90 :
91 : #if __cplusplus >= 202002L
92 : template<typename _Tp, typename... _Args>
93 : constexpr auto
94 : construct_at(_Tp* __location, _Args&&... __args)
95 : noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
96 : -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
97 : { return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
98 : #endif // C++20
99 : #endif// C++17
100 :
101 : /**
102 : * Constructs an object in existing memory by invoking an allocated
103 : * object's constructor with an initializer.
104 : */
105 : #if __cplusplus >= 201103L
106 : template<typename _Tp, typename... _Args>
107 : _GLIBCXX20_CONSTEXPR
108 : inline void
109 : _Construct(_Tp* __p, _Args&&... __args)
110 : {
111 : #if __cplusplus >= 202002L
112 : if (std::__is_constant_evaluated())
113 : {
114 : // Allow std::_Construct to be used in constant expressions.
115 : std::construct_at(__p, std::forward<_Args>(__args)...);
116 : return;
117 : }
118 : #endif
119 : ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
120 : }
121 : #else
122 : template<typename _T1, typename _T2>
123 : inline void
124 : _Construct(_T1* __p, const _T2& __value)
125 : {
126 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
127 : // 402. wrong new expression in [some_]allocator::construct
128 : ::new(static_cast<void*>(__p)) _T1(__value);
129 : }
130 : #endif
131 :
132 : template<typename _T1>
133 : inline void
134 : _Construct_novalue(_T1* __p)
135 : { ::new((void*)__p) _T1; }
136 :
137 : template<typename _ForwardIterator>
138 : _GLIBCXX20_CONSTEXPR void
139 : _Destroy(_ForwardIterator __first, _ForwardIterator __last);
140 :
141 : /**
142 : * Destroy the object pointed to by a pointer type.
143 : */
144 : template<typename _Tp>
145 : _GLIBCXX14_CONSTEXPR inline void
146 9198 : _Destroy(_Tp* __pointer)
147 : {
148 : #if __cplusplus > 201703L
149 : std::destroy_at(__pointer);
150 : #else
151 9198 : __pointer->~_Tp();
152 : #endif
153 : }
154 :
155 : template<bool>
156 : struct _Destroy_aux
157 : {
158 : template<typename _ForwardIterator>
159 : static _GLIBCXX20_CONSTEXPR void
160 : __destroy(_ForwardIterator __first, _ForwardIterator __last)
161 : {
162 15021 : for (; __first != __last; ++__first)
163 9198 : std::_Destroy(std::__addressof(*__first));
164 : }
165 : };
166 :
167 : template<>
168 : struct _Destroy_aux<true>
169 : {
170 : template<typename _ForwardIterator>
171 : static void
172 : __destroy(_ForwardIterator, _ForwardIterator) { }
173 : };
174 :
175 : /**
176 : * Destroy a range of objects. If the value_type of the object has
177 : * a trivial destructor, the compiler should optimize all of this
178 : * away, otherwise the objects' destructors must be invoked.
179 : */
180 : template<typename _ForwardIterator>
181 : _GLIBCXX20_CONSTEXPR inline void
182 : _Destroy(_ForwardIterator __first, _ForwardIterator __last)
183 : {
184 : typedef typename iterator_traits<_ForwardIterator>::value_type
185 : _Value_type;
186 : #if __cplusplus >= 201103L
187 : // A deleted destructor is trivial, this ensures we reject such types:
188 : static_assert(is_destructible<_Value_type>::value,
189 : "value type is destructible");
190 : #endif
191 : #if __cplusplus >= 202002L
192 : if (std::__is_constant_evaluated())
193 : return _Destroy_aux<false>::__destroy(__first, __last);
194 : #endif
195 : std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
196 : __destroy(__first, __last);
197 : }
198 :
199 : template<bool>
200 : struct _Destroy_n_aux
201 : {
202 : template<typename _ForwardIterator, typename _Size>
203 : static _GLIBCXX20_CONSTEXPR _ForwardIterator
204 : __destroy_n(_ForwardIterator __first, _Size __count)
205 : {
206 : for (; __count > 0; (void)++__first, --__count)
207 : std::_Destroy(std::__addressof(*__first));
208 : return __first;
209 : }
210 : };
211 :
212 : template<>
213 : struct _Destroy_n_aux<true>
214 : {
215 : template<typename _ForwardIterator, typename _Size>
216 : static _ForwardIterator
217 : __destroy_n(_ForwardIterator __first, _Size __count)
218 : {
219 : std::advance(__first, __count);
220 : return __first;
221 : }
222 : };
223 :
224 : /**
225 : * Destroy a range of objects. If the value_type of the object has
226 : * a trivial destructor, the compiler should optimize all of this
227 : * away, otherwise the objects' destructors must be invoked.
228 : */
229 : template<typename _ForwardIterator, typename _Size>
230 : _GLIBCXX20_CONSTEXPR inline _ForwardIterator
231 : _Destroy_n(_ForwardIterator __first, _Size __count)
232 : {
233 : typedef typename iterator_traits<_ForwardIterator>::value_type
234 : _Value_type;
235 : #if __cplusplus >= 201103L
236 : // A deleted destructor is trivial, this ensures we reject such types:
237 : static_assert(is_destructible<_Value_type>::value,
238 : "value type is destructible");
239 : #endif
240 : #if __cplusplus >= 202002L
241 : if (std::__is_constant_evaluated())
242 : return _Destroy_n_aux<false>::__destroy_n(__first, __count);
243 : #endif
244 : return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
245 : __destroy_n(__first, __count);
246 : }
247 :
248 : #if __cplusplus >= 201703L
249 : template <typename _ForwardIterator>
250 : _GLIBCXX20_CONSTEXPR inline void
251 : destroy(_ForwardIterator __first, _ForwardIterator __last)
252 : {
253 : std::_Destroy(__first, __last);
254 : }
255 :
256 : template <typename _ForwardIterator, typename _Size>
257 : _GLIBCXX20_CONSTEXPR inline _ForwardIterator
258 : destroy_n(_ForwardIterator __first, _Size __count)
259 : {
260 : return std::_Destroy_n(__first, __count);
261 : }
262 : #endif // C++17
263 :
264 : _GLIBCXX_END_NAMESPACE_VERSION
265 : } // namespace std
266 :
267 : #endif /* _STL_CONSTRUCT_H */
|