1    	// nonstandard construct and destroy functions -*- C++ -*-
2    	
3    	// Copyright (C) 2001-2017 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 <ext/alloc_traits.h>
62   	
63   	namespace std _GLIBCXX_VISIBILITY(default)
64   	{
65   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
66   	
67   	  /**
68   	   * Constructs an object in existing memory by invoking an allocated
69   	   * object's constructor with an initializer.
70   	   */
71   	#if __cplusplus >= 201103L
72   	  template<typename _T1, typename... _Args>
73   	    inline void
74   	    _Construct(_T1* __p, _Args&&... __args)
75   	    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
76   	#else
77   	  template<typename _T1, typename _T2>
78   	    inline void
79   	    _Construct(_T1* __p, const _T2& __value)
80   	    {
81   	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
82   	      // 402. wrong new expression in [some_]allocator::construct
83   	      ::new(static_cast<void*>(__p)) _T1(__value);
84   	    }
85   	#endif
86   	
87   	  template<typename _T1>
88   	    inline void
89   	    _Construct_novalue(_T1* __p)
90   	    { ::new(static_cast<void*>(__p)) _T1; }
91   	
92   	  /**
93   	   * Destroy the object pointed to by a pointer type.
94   	   */
95   	  template<typename _Tp>
96   	    inline void
97   	    _Destroy(_Tp* __pointer)
98   	    { __pointer->~_Tp(); }
99   	
100  	  template<bool>
101  	    struct _Destroy_aux
102  	    {
103  	      template<typename _ForwardIterator>
104  	        static void
105  	        __destroy(_ForwardIterator __first, _ForwardIterator __last)
106  		{
107  		  for (; __first != __last; ++__first)
108  		    std::_Destroy(std::__addressof(*__first));
109  		}
110  	    };
111  	
112  	  template<>
113  	    struct _Destroy_aux<true>
114  	    {
115  	      template<typename _ForwardIterator>
116  	        static void
117  	        __destroy(_ForwardIterator, _ForwardIterator) { }
118  	    };
119  	
120  	  /**
121  	   * Destroy a range of objects.  If the value_type of the object has
122  	   * a trivial destructor, the compiler should optimize all of this
123  	   * away, otherwise the objects' destructors must be invoked.
124  	   */
125  	  template<typename _ForwardIterator>
126  	    inline void
127  	    _Destroy(_ForwardIterator __first, _ForwardIterator __last)
128  	    {
129  	      typedef typename iterator_traits<_ForwardIterator>::value_type
130  	                       _Value_type;
131  	#if __cplusplus >= 201103L
132  	      // A deleted destructor is trivial, this ensures we reject such types:
133  	      static_assert(is_destructible<_Value_type>::value,
134  			    "value type is destructible");
135  	#endif
136  	      std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
137  		__destroy(__first, __last);
138  	    }
139  	
140  	  template<bool>
141  	    struct _Destroy_n_aux
142  	    {
143  	      template<typename _ForwardIterator, typename _Size>
144  	        static _ForwardIterator
145  	        __destroy_n(_ForwardIterator __first, _Size __count)
146  		{
147  		  for (; __count > 0; (void)++__first, --__count)
148  		    std::_Destroy(std::__addressof(*__first));
149  		  return __first;
150  		}
151  	    };
152  	
153  	  template<>
154  	    struct _Destroy_n_aux<true>
155  	    {
156  	      template<typename _ForwardIterator, typename _Size>
157  	        static _ForwardIterator
158  	        __destroy_n(_ForwardIterator __first, _Size __count)
159  		{
160  		  std::advance(__first, __count);
161  		  return __first;
162  		}
163  	    };
164  	
165  	  /**
166  	   * Destroy a range of objects.  If the value_type of the object has
167  	   * a trivial destructor, the compiler should optimize all of this
168  	   * away, otherwise the objects' destructors must be invoked.
169  	   */
170  	  template<typename _ForwardIterator, typename _Size>
171  	    inline _ForwardIterator
172  	    _Destroy_n(_ForwardIterator __first, _Size __count)
173  	    {
174  	      typedef typename iterator_traits<_ForwardIterator>::value_type
175  	                       _Value_type;
176  	#if __cplusplus >= 201103L
177  	      // A deleted destructor is trivial, this ensures we reject such types:
178  	      static_assert(is_destructible<_Value_type>::value,
179  			    "value type is destructible");
180  	#endif
181  	      return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
182  		__destroy_n(__first, __count);
183  	    }
184  	
185  	  /**
186  	   * Destroy a range of objects using the supplied allocator.  For
187  	   * nondefault allocators we do not optimize away invocation of 
188  	   * destroy() even if _Tp has a trivial destructor.
189  	   */
190  	
191  	  template<typename _ForwardIterator, typename _Allocator>
192  	    void
193  	    _Destroy(_ForwardIterator __first, _ForwardIterator __last,
194  		     _Allocator& __alloc)
195  	    {
196  	      typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
197  	      for (; __first != __last; ++__first)
198  		__traits::destroy(__alloc, std::__addressof(*__first));
199  	    }
200  	
201  	  template<typename _ForwardIterator, typename _Tp>
202  	    inline void
203  	    _Destroy(_ForwardIterator __first, _ForwardIterator __last,
204  		     allocator<_Tp>&)
205  	    {
206  	      _Destroy(__first, __last);
207  	    }
208  	
209  	#if __cplusplus > 201402L
210  	  template <typename _Tp>
211  	    inline void
212  	    destroy_at(_Tp* __location)
213  	    {
214  	      std::_Destroy(__location);
215  	    }
216  	
217  	  template <typename _ForwardIterator>
218  	    inline void
219  	    destroy(_ForwardIterator __first, _ForwardIterator __last)
220  	    {
221  	      std::_Destroy(__first, __last);
222  	    }
223  	
224  	  template <typename _ForwardIterator, typename _Size>
225  	    inline _ForwardIterator
226  	    destroy_n(_ForwardIterator __first, _Size __count)
227  	    {
228  	      return std::_Destroy_n(__first, __count);
229  	    }
230  	#endif
231  	
232  	_GLIBCXX_END_NAMESPACE_VERSION
233  	} // namespace std
234  	
235  	#endif /* _STL_CONSTRUCT_H */
236  	
237