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