Line data Source code
1 : // nonstandard construct and destroy functions -*- C++ -*-
2 :
3 : // Copyright (C) 2001-2020 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 > 201703L
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 : inline void
108 0 : _Construct(_Tp* __p, _Args&&... __args)
109 0 : { ::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...); }
110 : #else
111 : template<typename _T1, typename _T2>
112 : inline void
113 : _Construct(_T1* __p, const _T2& __value)
114 : {
115 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
116 : // 402. wrong new expression in [some_]allocator::construct
117 : ::new(static_cast<void*>(__p)) _T1(__value);
118 : }
119 : #endif
120 :
121 : template<typename _T1>
122 : inline void
123 : _Construct_novalue(_T1* __p)
124 : { ::new(static_cast<void*>(__p)) _T1; }
125 :
126 : template<typename _ForwardIterator>
127 : _GLIBCXX20_CONSTEXPR void
128 : _Destroy(_ForwardIterator __first, _ForwardIterator __last);
129 :
130 : /**
131 : * Destroy the object pointed to by a pointer type.
132 : */
133 : template<typename _Tp>
134 : _GLIBCXX14_CONSTEXPR inline void
135 0 : _Destroy(_Tp* __pointer)
136 : {
137 : #if __cplusplus > 201703L
138 : std::destroy_at(__pointer);
139 : #else
140 0 : __pointer->~_Tp();
141 : #endif
142 0 : }
143 :
144 : template<bool>
145 : struct _Destroy_aux
146 : {
147 : template<typename _ForwardIterator>
148 : static _GLIBCXX20_CONSTEXPR void
149 1278 : __destroy(_ForwardIterator __first, _ForwardIterator __last)
150 : {
151 1278 : for (; __first != __last; ++__first)
152 0 : std::_Destroy(std::__addressof(*__first));
153 1278 : }
154 : };
155 :
156 : template<>
157 : struct _Destroy_aux<true>
158 : {
159 : template<typename _ForwardIterator>
160 : static void
161 1420 : __destroy(_ForwardIterator, _ForwardIterator) { }
162 : };
163 :
164 : /**
165 : * Destroy a range of objects. If the value_type of the object has
166 : * a trivial destructor, the compiler should optimize all of this
167 : * away, otherwise the objects' destructors must be invoked.
168 : */
169 : template<typename _ForwardIterator>
170 : _GLIBCXX20_CONSTEXPR inline void
171 2698 : _Destroy(_ForwardIterator __first, _ForwardIterator __last)
172 : {
173 : typedef typename iterator_traits<_ForwardIterator>::value_type
174 : _Value_type;
175 : #if __cplusplus >= 201103L
176 : // A deleted destructor is trivial, this ensures we reject such types:
177 : static_assert(is_destructible<_Value_type>::value,
178 : "value type is destructible");
179 : #endif
180 : #if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
181 : if (std::is_constant_evaluated())
182 : return _Destroy_aux<false>::__destroy(__first, __last);
183 : #endif
184 : std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
185 2698 : __destroy(__first, __last);
186 2698 : }
187 :
188 : template<bool>
189 : struct _Destroy_n_aux
190 : {
191 : template<typename _ForwardIterator, typename _Size>
192 : static _GLIBCXX20_CONSTEXPR _ForwardIterator
193 : __destroy_n(_ForwardIterator __first, _Size __count)
194 : {
195 : for (; __count > 0; (void)++__first, --__count)
196 : std::_Destroy(std::__addressof(*__first));
197 : return __first;
198 : }
199 : };
200 :
201 : template<>
202 : struct _Destroy_n_aux<true>
203 : {
204 : template<typename _ForwardIterator, typename _Size>
205 : static _ForwardIterator
206 : __destroy_n(_ForwardIterator __first, _Size __count)
207 : {
208 : std::advance(__first, __count);
209 : return __first;
210 : }
211 : };
212 :
213 : /**
214 : * Destroy a range of objects. If the value_type of the object has
215 : * a trivial destructor, the compiler should optimize all of this
216 : * away, otherwise the objects' destructors must be invoked.
217 : */
218 : template<typename _ForwardIterator, typename _Size>
219 : _GLIBCXX20_CONSTEXPR inline _ForwardIterator
220 : _Destroy_n(_ForwardIterator __first, _Size __count)
221 : {
222 : typedef typename iterator_traits<_ForwardIterator>::value_type
223 : _Value_type;
224 : #if __cplusplus >= 201103L
225 : // A deleted destructor is trivial, this ensures we reject such types:
226 : static_assert(is_destructible<_Value_type>::value,
227 : "value type is destructible");
228 : #endif
229 : #if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
230 : if (std::is_constant_evaluated())
231 : return _Destroy_n_aux<false>::__destroy_n(__first, __count);
232 : #endif
233 : return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
234 : __destroy_n(__first, __count);
235 : }
236 :
237 : #if __cplusplus >= 201703L
238 : template <typename _ForwardIterator>
239 : _GLIBCXX20_CONSTEXPR inline void
240 : destroy(_ForwardIterator __first, _ForwardIterator __last)
241 : {
242 : std::_Destroy(__first, __last);
243 : }
244 :
245 : template <typename _ForwardIterator, typename _Size>
246 : _GLIBCXX20_CONSTEXPR inline _ForwardIterator
247 : destroy_n(_ForwardIterator __first, _Size __count)
248 : {
249 : return std::_Destroy_n(__first, __count);
250 : }
251 : #endif // C++17
252 :
253 : _GLIBCXX_END_NAMESPACE_VERSION
254 : } // namespace std
255 :
256 : #endif /* _STL_CONSTRUCT_H */
|