libstdc++
|
00001 // nonstandard construct and destroy functions -*- C++ -*- 00002 00003 // Copyright (C) 2001-2017 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /* 00026 * 00027 * Copyright (c) 1994 00028 * Hewlett-Packard Company 00029 * 00030 * Permission to use, copy, modify, distribute and sell this software 00031 * and its documentation for any purpose is hereby granted without fee, 00032 * provided that the above copyright notice appear in all copies and 00033 * that both that copyright notice and this permission notice appear 00034 * in supporting documentation. Hewlett-Packard Company makes no 00035 * representations about the suitability of this software for any 00036 * purpose. It is provided "as is" without express or implied warranty. 00037 * 00038 * 00039 * Copyright (c) 1996,1997 00040 * Silicon Graphics Computer Systems, Inc. 00041 * 00042 * Permission to use, copy, modify, distribute and sell this software 00043 * and its documentation for any purpose is hereby granted without fee, 00044 * provided that the above copyright notice appear in all copies and 00045 * that both that copyright notice and this permission notice appear 00046 * in supporting documentation. Silicon Graphics makes no 00047 * representations about the suitability of this software for any 00048 * purpose. It is provided "as is" without express or implied warranty. 00049 */ 00050 00051 /** @file bits/stl_construct.h 00052 * This is an internal header file, included by other library headers. 00053 * Do not attempt to use it directly. @headername{memory} 00054 */ 00055 00056 #ifndef _STL_CONSTRUCT_H 00057 #define _STL_CONSTRUCT_H 1 00058 00059 #include <new> 00060 #include <bits/move.h> 00061 #include <ext/alloc_traits.h> 00062 00063 namespace std _GLIBCXX_VISIBILITY(default) 00064 { 00065 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00066 00067 /** 00068 * Constructs an object in existing memory by invoking an allocated 00069 * object's constructor with an initializer. 00070 */ 00071 #if __cplusplus >= 201103L 00072 template<typename _T1, typename... _Args> 00073 inline void 00074 _Construct(_T1* __p, _Args&&... __args) 00075 { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 00076 #else 00077 template<typename _T1, typename _T2> 00078 inline void 00079 _Construct(_T1* __p, const _T2& __value) 00080 { 00081 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00082 // 402. wrong new expression in [some_]allocator::construct 00083 ::new(static_cast<void*>(__p)) _T1(__value); 00084 } 00085 #endif 00086 00087 template<typename _T1> 00088 inline void 00089 _Construct_novalue(_T1* __p) 00090 { ::new(static_cast<void*>(__p)) _T1; } 00091 00092 /** 00093 * Destroy the object pointed to by a pointer type. 00094 */ 00095 template<typename _Tp> 00096 inline void 00097 _Destroy(_Tp* __pointer) 00098 { __pointer->~_Tp(); } 00099 00100 template<bool> 00101 struct _Destroy_aux 00102 { 00103 template<typename _ForwardIterator> 00104 static void 00105 __destroy(_ForwardIterator __first, _ForwardIterator __last) 00106 { 00107 for (; __first != __last; ++__first) 00108 std::_Destroy(std::__addressof(*__first)); 00109 } 00110 }; 00111 00112 template<> 00113 struct _Destroy_aux<true> 00114 { 00115 template<typename _ForwardIterator> 00116 static void 00117 __destroy(_ForwardIterator, _ForwardIterator) { } 00118 }; 00119 00120 /** 00121 * Destroy a range of objects. If the value_type of the object has 00122 * a trivial destructor, the compiler should optimize all of this 00123 * away, otherwise the objects' destructors must be invoked. 00124 */ 00125 template<typename _ForwardIterator> 00126 inline void 00127 _Destroy(_ForwardIterator __first, _ForwardIterator __last) 00128 { 00129 typedef typename iterator_traits<_ForwardIterator>::value_type 00130 _Value_type; 00131 #if __cplusplus >= 201103L 00132 // A deleted destructor is trivial, this ensures we reject such types: 00133 static_assert(is_destructible<_Value_type>::value, 00134 "value type is destructible"); 00135 #endif 00136 std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: 00137 __destroy(__first, __last); 00138 } 00139 00140 template<bool> 00141 struct _Destroy_n_aux 00142 { 00143 template<typename _ForwardIterator, typename _Size> 00144 static _ForwardIterator 00145 __destroy_n(_ForwardIterator __first, _Size __count) 00146 { 00147 for (; __count > 0; (void)++__first, --__count) 00148 std::_Destroy(std::__addressof(*__first)); 00149 return __first; 00150 } 00151 }; 00152 00153 template<> 00154 struct _Destroy_n_aux<true> 00155 { 00156 template<typename _ForwardIterator, typename _Size> 00157 static _ForwardIterator 00158 __destroy_n(_ForwardIterator __first, _Size __count) 00159 { 00160 std::advance(__first, __count); 00161 return __first; 00162 } 00163 }; 00164 00165 /** 00166 * Destroy a range of objects. If the value_type of the object has 00167 * a trivial destructor, the compiler should optimize all of this 00168 * away, otherwise the objects' destructors must be invoked. 00169 */ 00170 template<typename _ForwardIterator, typename _Size> 00171 inline _ForwardIterator 00172 _Destroy_n(_ForwardIterator __first, _Size __count) 00173 { 00174 typedef typename iterator_traits<_ForwardIterator>::value_type 00175 _Value_type; 00176 #if __cplusplus >= 201103L 00177 // A deleted destructor is trivial, this ensures we reject such types: 00178 static_assert(is_destructible<_Value_type>::value, 00179 "value type is destructible"); 00180 #endif 00181 return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>:: 00182 __destroy_n(__first, __count); 00183 } 00184 00185 /** 00186 * Destroy a range of objects using the supplied allocator. For 00187 * nondefault allocators we do not optimize away invocation of 00188 * destroy() even if _Tp has a trivial destructor. 00189 */ 00190 00191 template<typename _ForwardIterator, typename _Allocator> 00192 void 00193 _Destroy(_ForwardIterator __first, _ForwardIterator __last, 00194 _Allocator& __alloc) 00195 { 00196 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00197 for (; __first != __last; ++__first) 00198 __traits::destroy(__alloc, std::__addressof(*__first)); 00199 } 00200 00201 template<typename _ForwardIterator, typename _Tp> 00202 inline void 00203 _Destroy(_ForwardIterator __first, _ForwardIterator __last, 00204 allocator<_Tp>&) 00205 { 00206 _Destroy(__first, __last); 00207 } 00208 00209 #if __cplusplus > 201402L 00210 template <typename _Tp> 00211 inline void 00212 destroy_at(_Tp* __location) 00213 { 00214 std::_Destroy(__location); 00215 } 00216 00217 template <typename _ForwardIterator> 00218 inline void 00219 destroy(_ForwardIterator __first, _ForwardIterator __last) 00220 { 00221 std::_Destroy(__first, __last); 00222 } 00223 00224 template <typename _ForwardIterator, typename _Size> 00225 inline _ForwardIterator 00226 destroy_n(_ForwardIterator __first, _Size __count) 00227 { 00228 return std::_Destroy_n(__first, __count); 00229 } 00230 #endif 00231 00232 _GLIBCXX_END_NAMESPACE_VERSION 00233 } // namespace std 00234 00235 #endif /* _STL_CONSTRUCT_H */ 00236